적중률과 삭제 규칙
캐시가 얼마나 효율적으로 사용되는지는 적중률 로 판단 가능.
- Hit Rate: 캐시에 존재한 건수 / 캐시에서 조회를 시도한 건수 캐시에서 데이터 100번 조회했는데 그중 87번은 존재했으면 적중률은 87%가 되는것.
적중률 높이는 가장 간단한 방법은 캐시에 많이 저장해놓는것. 하지만 메모리 자원쓰니 무식하게 저장하면 안된다.
캐시에 보관할 수 있는 데이터에 제한이 있으니 캐시가 가득 차 있는 상태에서 새로운 데이터를 캐시에 저장하면 기존에 있던 데이터 하나를 제거해야한다. 삭제 대상을 선택할 때 주로 사용하는 규칙은 다음과 같다.
- LRU(Least Recently Used): 가장 오래전 사용한 데이터 제거
- LFU(Least Frequently Used): 가장 적게 사용된 데이터 제거
- FIFO: 먼저 추가된 데이터 먼저 삭제
로컬 캐시와 리모트 캐시
- 로컬 캐시(인메모리 캐시): 서버 프로세스와 동일한 메모리를 캐시 저장소로 씀
- 리모트 캐시: 별도 프로세스를 캐시 저장소로 사용 로컬 캐시 기술로는 Caffeine, go-cache, node-cache 등. 장점은 바로 속도. 서버와 캐시가 동일한 메모리 공간을 사용하므로 캐시 데이터에 빠르게 접근 가능. 또한 별도 외부 연동이 필요 없어 구조를 단순히 유지 가능
로컬 캐시 단점은 캐시에 저장가능한 데이터 크기에 제한이 있다는 점. 또한 서버 프로세스 재시작시 캐시가 클리어 되는 단점도 있음.
리모트 캐시는 로컬 캐시와 반대 장단점 가진다. 가장 큰 장점은 캐시 크기를 유연히 확장할 수 있는것. 대표적인 리모트 캐시 기술인 레디스는 여러 대의 레디스 서버를 이용해 수평 확장할 수 있는 기능을 제공한다.
단점은 속도인데 서버 프로세스는 캐시 프로세스와 데이터 주고받기 위해 네트워크 통신을 해야한다. 같은 프로세스 메모리에 직접 접근하는 것과 비교하면 상대적으로 느리다. 또한 리모트 캐시를 운영하려면 별도의 서버 장비와 프로세스가 필요해서 시스템 구조가 복잡해진다.
- 로컬 캐시
- 캐시 규모 작다면
- 캐시 변경 빈도 낮다면
- 리모트 캐시
- 데이터 규모 클때
- 대형 소핑 사이트 개별 제품 정보 이런건 로컬 캐시로 대응 한계 존대
- 일부 로컬에 넣어도 데이터가 수시로 변경되면 캐시 효율도 떨어짐
- 배포 빈도 높을때
- 이건 서버와 무관하니까 캐시 적재된게 유지됨
캐시 사전 적재
트래픽이 순간적으로 급증하는 패턴 있다면 캐시에 데이터를 미리 적재하는 것도 고려해볼만하다. 다음은 캐시 사전 적재에 큰 효과가 있는 사례
- 앱 사용자는 300만명
- 앱 서비스는 사용자에게 매달 정해진 날에 이달의 요금 정보 보여준다.
- 해당 일자 되면 전체 회원 대상으로 요금 안내 푸시 알림 발송
- 푸시를 받은 사용자 중 일부는 앱 통해 이달의 요금 정보 조회 이 사례에서 푸시 알림 받은 사용자는 앱을 실행해 즉시 요금 정보를 조회한다. 푸시를 받자마자 50% 사용자가 바로 확인한다면 단시간에 150만명이 접속하게된다. 이때 캐시 적중률은 순간적으로 0%에 가까워질 수 있다. 아직 사용자 개별 정보가 캐시에 저장되지 않았기 때문.
캐시 적중률이 낮아지면 전체 응답 시간이 느려지고 DB에 전달되는 부하도 급격히 증가한다. 이를 방지하는게 캐시 미리 적재. 300만명의 사용자에게 푸시 알림 보내기 전에 캐시해두면 한번에 사용자 몰려도 캐시 적중률을 99% 가깝게 유지할 수 있다.
캐시 무효화
캐시 사용시 신경써야되는건 적절한 시점에 캐시에서 데이터를 제거하는 것이다. 캐시의 원본이 바뀌면 그에 맞춰 캐싱된 데이터도 동기화 해줘야한다. 데이터 정합성을 지켜야지.
캐시의 저장된 데이터 특성에 따라 캐시를 무효화하는 시점을 달리 설정해야 한다. 가격 정보, 게시글 내용처럼 민감한 데이터는 변경 즉시 캐시를 무효화 해야한다. 수정이 제대로 반영되지 않았다고 생각하면 사용자는 오류를 신고하거나 서비스 신뢰도를 낮게 평가할 수도 있다.
변경에 민감한 데이터는 로컬이아닌 리모트에 보관해야한다. 로컬 캐시는 자기의 데이터만 변경하지 다른 서버의 로컬 캐시는 변경하지 않기 때문이다. (동기화 가능하긴 하다)
변경에 둔감한 데이터는 캐시 유효 시간 주어 주기적 갱신 방식 써도 된다. 예를 들어 최근 인기 글 목록을 캐시한 후 최근 인기 글 목록이 바뀌고 몇분 뒤 캐시 데이터가 바뀌더라도 서비스에 심각한 문제는 발생안함. 캐시 유효 기간을 10분으로 하면 10분 주기로 최신 인기 게시글 목록을 갱신하는 효과 얻을 수 있다.