[OSSCA] valkey cache
Memory Cache를 이용하게 되면 훨씬 더 빠른 속도로 서비스가 가능하다.
- Look aside Cache
- Web Server는 데이터가 존재하는지 cache를 먼저 확인
- Cache에 데이터가 있으면 Cache에서 가져온다.
- Cache에 데이터가 없다면 DB에서 읽어온다.
- DB에서 읽어온 데이터를 Cache에 다시 저장한다.
- Write Back
- Web Server는 모든 데이터를 Cache에만 저장
- Cache에 특정 시간동안의 데이터가 저장
- Cache에 있는 데이터를 DB에 저장한다.
- 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를 터지지 않게 유지한다.