기타

Redis

Hoonco 2023. 1. 18. 02:39

Redis?

Redis란 key-value 형태의 NoSQL InMemory DB 입니다. 

대표적으로 분산환경에서의 세션 관리, 캐싱에 자주 활용됩니다.

 

왜 Redis를 사용하는가?

같은 InMemory DB들중 대표 적인 것 중에 하나닥 Memcached가 있습니다.

둘의 가장 큰 차이점은 Redis는 싱글 스레드, Memcahaced는 멀티 스레드 환경이라는 것이고,

Redis는 List, Set, SortedSet 등 여러 Collection들을 지원한다는 것입니다.

 

또한 Memcached는 Redis에서 지원하는 스냅샷, Replication, Trasaction 등 지원하지 않는 기능이 꽤 많으며

Memcached는 주로 Scale up을 활용해서 확장성을 얻을 수 있는 반면, Redis는 Scale out을 통해 얻을 수 있기에 
Redis가 좀더 선호되는 경향이 있습니다.

 

어떻게 데이터를 안정적으로 보관할 수 있는가?

항상 메모리에서 가장 중요되는 점은 임계구역 관련된 Race Condtion 문제입니다.

Race Condtion이란 스레드들이 공통 자원을 병행적으로 접근하면서 경쟁 상태가 되는 것으로

정상적인 값이 나오지 않거나Deadlock 같은 문제를 야기할 수 있습니다.

 

그럼 Redis는 어떻게 이를 해결할까요?

Redis는 기본적으로 싱글 스레드로 동작합니다.

또한 Redis에서 사용되는 자료구조는 임계 구역에 대한 동기화를 자체적으로 제공합니다.

이덕분에 Race Condtion에 대해서 좀 더 안정적입니다.

 

하지만 위에서 언급 했다 싶이 Redis는 싱글 스레드이기 때문에 처리 속도가 매우 중요합니다.

O(n) 정도의 시간 복잡도를 가진 keys 명령어는 큰 문제를 야기할 수 있기 때문에 자제 하고 주의 해야 합니다.

 

캐시 환경

캐시 환경으로 Redis를 사용할 때 꼭 설정해주어야 하는 것이 있습니다.

바로 maxmemory-policy 입니다. 

메모리가 꽉찼을 때 어떤 방식으로 해결할 것인지에 대해 정하는 설정 값입니다.

 

설정 값들의 종류는 아래와 같습니다.

정책 설명
noeviction (default)  기존 데이터를 삭제 안하여서, 메모리 한계에 도달하면 OOM 오류를 반환하며 새 데이터가 저장되지 않습니다.
volatile-lru 만료 시간을 가진 데이터 중 LRU, 즉 최근에 가장 적게 사용된 데이터를 삭제하는 방식입니다.
volatile-ttl 만료 시간을 가진 데이터 중 가장 TTL이 짧은 것부터 삭제합니다.
volatile-random 만료시간을 가진 데이터를 랜덤하게 삭제합니다.
allkeys-lru 모든 데이터 중 LRU기준으로 데이터를 삭제합니다.
allkeys-random 모든 데이터중 랜덤하게 삭제합니다.

대부분의 캐싱 환경에선 allkeys-lru 방식으로 설정하여 사용하게 됩니다.

 

캐싱 전략

캐싱 전략에는 읽기(조회), 쓰기(저장) 전략으로 나뉩니다.

 

읽기 전략엔 Look Aside, Read Through 가있습니다.

 

Look Aside란 데이터 조회시 DB에 바로 접근하는 것이 아닌 캐시를 한번 거쳐서 있다면 캐시에서 바로 반환하고 

아니라면 DB에서 조회하는 방식입니다.

이 방식은 캐시에 장애가 발생하더라도 DB로 접근하도록 하기 때문에 장애를 대비할 수 있지만.

DB간 데이터 정합성 유지, 장애시 DB로 트래픽이 몰리는 등의 단점이 있습니다.

이런 경우 DB에서 캐시로 데이터를 미리 넣어주는 작업을 하는데 이를 Cache Warming이라고 합니다.

 

Read Through란 캐시에서만 데이터를 읽어오는 전략으로 Look Aside
비슷하지만 데이터 동기화를 라이브러리나 캐시 제공자에게 위임하는 방식이라는 차이가 있습니다.

이 방식은 데이터를 조회하는데 있어 속도가 조금 느리고 Redis가 다운된 경우 서비스에 큰 차질이 생길 수 있지만

캐시와 DB간 데이터 동기화가 항상 이루어짐으로 데이터 정합성 문제에서 벗어날 수 있습니다.

 

 

쓰기 전략엔 Write Back, Write Through, Write Around 등이 있습니다.

 

Write Back이란 캐시에 지속적으로 데이터를 저장한 후에 일정 주기 배치 작업을 통해 DB에 반영하는 방식입니다.

데이터 정합성과, DB에 대한 부하를 최소한으로 줄일 수 있지만.

캐시에서 오류가 발생하게 되면 데이터를 영구적으로 손실할 수 있다는 점이 있습니다.

 

Write Through란 데이터베이스와 Cache에 동시에 데이터를 저장하는 전략입니다.

데이터를 저장할때 먼저 캐시에 저장한 후 바로 DB에 저장하는 방식이다.

Read Through와 마찬가지로 DB 동기화 작업을 캐시에게 위임하게된다.

항상 동기화가 되어있고 캐시에선 데이터를 항상 최신으로 유지할 수 있다.

 

하지만 자주 사용되지 않는 리소스들도 저장하게 되고, 매 요청시 Write가 두번 발생함으로 빈번한 생성, 수정이 발생하는 서비스에선 성능 이슈가 발생합니다.

 

Write Around는 모든 데이터를 DB에 저장하고 ( 캐시 갱신 X ) 캐시 미스가 나는 경우에만 DB와 캐시에 데이터를 저장합니다.

이때문에 캐시와 DB와의 데이터 불일치가 발생될 수 있습니다.

 

 

Look Aside + Write Around 조합은 가장 일반적으로 쓰이고

Read Through + Write Around 조합은 데이터 정합성에 대한 완벽한 안정장치가 구성될 수 있고

Read Through + Write Through 조합은 캐시에 항상 최신 데이터가 보장된다는 점입니다.