포스트

[OSSCA] valkey cache

Memory Cache를 이용하게 되면 훨씬 더 빠른 속도로 서비스가 가능하다.

- Look aside Cache

  1. Web Server는 데이터가 존재하는지 cache를 먼저 확인
  2. Cache에 데이터가 있으면 Cache에서 가져온다.
  3. Cache에 데이터가 없다면 DB에서 읽어온다.
  4. DB에서 읽어온 데이터를 Cache에 다시 저장한다.

- Write Back

  1. Web Server는 모든 데이터를 Cache에만 저장
  2. Cache에 특정 시간동안의 데이터가 저장
  3. Cache에 있는 데이터를 DB에 저장한다.
  4. Cache에 저장된 데이터를 삭제한다.

Q. Look aside Cache의 방식은 이해가 되는데 Write Back은 Cache에 왜 특정 시간동안만 저장하는지가 궁금하다. 

A. Write Back 저장 방식은 바로 DB에 저장하지 않고 캐시에 저장해뒀다가 특정 시간마다 한 번만 저장하기 때문에 빠르고 자원을 아낄 수 있다. 하지만 DB와 Cache에 저장된 데이터가 달라 불일치성이 발생한다.

예상 질문 

Q. API 응답 결과를 캐싱하려고 하는데, String 구조에 JSON 형태로 통째로 넣는 것과 Hash 구조로 필드를 나누어 넣는 것 중 어떤 것이 더 유리할까요?

A. 전체 조회 위주라면 String, 부분 수정이 잦다면 Hash가 유리하다.

String은 구현이 단순하고 데이터를 가져와서 바로 역직렬화하면 된다. 하지만 데이터 필드 하나를 바꾸려할 때 전체 데이터를 다시 쓰고 읽어야 해서 Race Condition이 발생할 위험이 크다.

Hash는 특정 필드만 업데이트할 때 효율적이고, 메모리 최적화 기법 덕분에 필드가 많지 않으면 메모리도 아낄 수 있다. 하지만 전체 데이터를 가져올 때는 여러번의 연산이 필요할 수 있어 String보단 느리다.

Q. 실시간 데이터를 분석해서 랭킹 보드를 만들 때 Sorted Set을 쓰면 탐색 시간 복잡도가 $O(\log N)$이 된다고 배웠는데, 데이터가 수백만 개로 늘어나도 병목이 없을까요?

A. 오늘 배운 시간복잡도를 같이 생각해보면 O(log n) 수준의 시간 복잡도로는 수백만 개 수준은 빠르게 해결 가능하다. 

log(1,000,000) = 약 20이다. (알고리즘에서는 상용로그가 아니라 이진로그를 사용한다.)

 하지만 전송 시간 대부분이라 범위 조회 부분에서 병목이 발생한다. 또한 싱글 스레드로 이루어져 있기 때문에 요청 대기 문제가 있다.

Q. 대용량 트래픽이 몰릴 때 캐시가 만료되면 DB에 부하가 집중될 텐데, 이때 배운 분산 락(Distributed Lock)을 어떻게 적용할 수 있을까요?

A. 수 만명의 사용자가 동시에 접속하면 캐시 스탬피드 현상이 발생한다. 그러므로 분산 락을 획득한 한 명만 DB에서 데이터를 읽어와서 캐시에 업데이트한다. 나머지 요청들은 대기하거나 이전의 데이터를 보여줘서 DB를 터지지 않게 유지한다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.