[Redis에 대하여] 2. 캐싱 전략

아양시·2023년 1월 5일
0

Redis에 대하여

목록 보기
2/3

  하루종일 열심히 이웃사이의 좋아요 기능에 대해 Redis를 어떤 전략으로 사용할 것인지 고민해봤다. 우선 어떤 캐싱 전략이 있는지 알아보기부터 시작했다. 캐싱 전략을 간략하게 정리해보면 다음과 같다.

캐싱 전략

(참고)

캐시 읽기 전략

  1. Look Aside(Lazy-Loading) 패턴 : 캐시에 데이터가 있는지 확인하고 없는 경우 디비에서 조회, 캐시에는 원하는 데이터만 별도로 구성해서 저장
  2. Read Through 패턴 : 캐시에 데이터가 있는지 확인하고 없는 경우 디비에서 캐시로 동기화 후 캐시에서 데이터 조회

캐시 쓰기 전략

  1. Write Back 패턴 : 캐시에 쓰고 일정 주기 배치 작업을 통해 디비에 반영
  2. Write Through 패턴 : 캐시에 먼저 쓴 다음 바로 디비에 저장
  3. Write Around 패턴 : 모든 데이터는 디비에 저장하고 캐시 미스가 발생하는 경우에만 캐시에도 저장


  이렇게 다양한 전략들이 있는 것을 알게된 후 본 서비스에는 어떤 요구사항이 있기 때문에 어떤 전략을 사용해야 할지, 해당 전략 사용 시 장단점이 뭔지, 구현은 어떻게 되는지에 대해 아래와 같은 아주 길고 긴 고민(뇌절)을 했다.

  사실 이 모든 것들은 지금의 작은 규모에서는 크게 상관이 없고, 대규모의 상황을 대비하는 것인데, Redis 를 사용해서 캐싱을 하는 것 자체가 대규모 트래픽에서도 좋은 성능을 유지하고자 하는 것이니 이왕 하는거 열심히 머리를 싸매봤다.

그래서 내린 결론은 다음과 같다.

  1. 대부분의 sns 서비스에서 빈번하게 사용되는 좋아요 기능을 누락되는 요청없이 신속정확하게 처리하기 위해 Redis를 사용한다.
  2. 많은 쓰기를 누락없이 처리하고, 정합성 있는 최신 정보를 제공하기 위해 Read Through & Write Back 전략을 사용한다. 즉, 캐시를 통해서만 읽고 쓴다.
  3. 캐시 데이터 삭제는 expire 설정으로 처리하고, 주기적으로 캐시에서 디비로 동기화한다.
  4. 캐시에서 디비로 동기화할 대상을 선별하기 위해 캐시에 수정된 데이터 키 목록인 board_key_list를 저장한다.
  5. 디비에 반영되기 전에 소멸되는 캐시 데이터를 최소화하기 위해 expire는 디비 동기화 주기보다 길게 설정한다. (너무 길면 캐시 메모리 용량 오버헤드 주의)
  6. 디비 반영 주기는 처리 시간이 길 것을 고려하여 너무 짧지 않게 정한다.

메모리에 너무 많은 데이터를 올리는 것이 아닌가?

  읽기와 쓰기 데이터를 모두 캐시에 올려서 사용하다보니 너무 많은 데이터를 메모리에 두는 게 아닌가 하는 생각이 들었다. 하지만, 기능 특성상, 쓰기 데이터는 모두 읽기 데이터에 포함되는 것들이고,(게시물을 봐야 좋아요를 누를 수 있으니) 본 서비스에서 캐시를 사용자 인증 정보(토큰) 저장 시와 좋아요 기능에서만 사용하기 때문에 비중을 조금 두어도 되지 않을까라고 생각했다.


캐시 의존성이 높은데, 캐시가 죽으면?

  1. 캐시 용량 관리를 위해 expire 주기를 최대한 짧게 조절해보자.
  2. 캐시가 죽기 전에 디비에 최대한 저장할 수 있도록 캐시에서 디비에 데이터를 반영하는 주기를 최대한 짧게 조절해보자.
  3. 규모가 더 커지면 Redis 서버를 여러 대 두고 Master-Slave 구조, 센티널 등을 고려해볼 수 있다.

캐시에서 디비로 어떻게 동기화할 것인가?

  우선 캐시에 있는 모든 데이터를 매번 디비에 동기화할 것이 아니기 때문에 동기화할 데이터를 선별하는 것이 필요하다고 생각했다. 그래서 디비로부터 상태가 변해서 동기화가 필요한 캐시 데이터의 키 즉, 사용자가 좋아요를 누른 게시물 ID의 목록을 저장하기 위해 앞서 언급한 board_key_list를 만들어봤다.

그러고 나서 지금까지는

  1. board_key_list에서 동기화할 게시물 ID 리스트 가져오기
  2. 각 ID별로 member Set 조회하기
  3. board_key_list 초기화하기
  4. 디비에서 해당 게시물 ID에 대한 member ID 리스트 가져와서 Set으로 변환하고 캐시 데이터랑 차집합 연산해서 필요에 따라 추가나 삭제하기

이렇게 생각해봤는데 아무래도 2번이랑 4번이 너무 오래 걸릴 것 같아서 트랜잭션 처리나 처리 순서 등을 조금 더 고민해봐야 할 것 같다. 필요에 따라 테이블에 인덱스 생성이나 비동기 처리 등을 고려해볼 수 있을 것이다.



나름대로 열심히 고민해봤지만 여전히 너무 큰 데이터가 너무 자주 왔다갔다 하는 것이 아닌가 하는 걱정이 있어서 계속 고민해봐야 할 것 같다.
profile
BE Developer

0개의 댓글