redis를 cache로 사용하는 방법을 알아보자.
캐시란
- 원본 데이터보다 더 빠르고 효율적으로 액세스 할 수 있는 임시 데이터 저장소
캐시 도입으로 성능을 개선할 수 있는 조건
- 데이터를 찾기 위해 검색하는 시간이 오래 걸리거나, 매번 계산을 통해 데이터를 가져와야 한다
- 캐시가 원본 데이터에 요청하는 것보다 빨라야 한다
- 캐시에 저장된 데이터가 잘 변하지 않는 데이터다
- 캐시에 저장된 데이터가 자주 검색되는 데이터다
캐시로서의 레디스
- 키/값 형태의 구성으로 간단하다
- 인메모리 데이터 저장소로 빠르다
- 자체적으로 고가용성 기능을 가지고 있는 솔루션이다
- 장애 시에도 안정적 운영이 가능
- 스케일 아웃을 손쉽게 할 수 있다
캐싱 전략
- 레디스를 어떻게 배치할 것인지에 따라 서비스 성능에 큰 영향을 끼친다
- 캐싱되는 데이터의 유형
- 데이터에 대한 액세스 패턴
읽기 전략 - look aside
- 캐시 먼저 체크, 있으면 캐시에서 읽고
- 없으면 DB에 접근
- 캐시 워밍 : 미리 데이터베이스에서 캐시로 데이터를 밀어 넣어주는 작업
쓰기 전략
- 캐시 불일치(inconsistency) : 데이터 변경으로 원본 데이터와 캐시 데이터 간의 불일치
- Write through
- 데이터베이스에 업데이트할 때마다 캐시에도 업데이트
- 매번 2개의 저장소에 저장돼야 하여 리소스가 많이 든다
- 만료 시간 사용을 권장
- Cache invalidation
- 데이터베이스에 업데이트할 때마다 캐시에 데이터 삭제
- Write behind
- 쓰기가 빈번하게 발생하는 서비스에 적합
- 먼저 캐시에만 반영, 건수나 특정 시간 간격으로 비동기적으로 데이터베이스 업데이트
- 데이터가 실시간으로 정확한 데이터가 아니어도 되는 경우
Cache - 데이터 관리
TTL(만료시간)(time to live)
- 데이터가 얼마나 오래 저장될 것인지 나타낸다
- Expire : 만료시간 설정
- Ex 옵션 : 저장할 때 만료시간 설정
- TTL : 만료시간 조회
- Incr, rename과 같이 데이터를 조작 키의 이름을 바꾸는 경우 만료시간이 변하지 않음
- 키를 덮어쓸 때는 만료시간이 사라진다
메모리 관리 / maxmemory-policy
- 메모리 용량을 초과하는 양의 데이터가 저장되면 레디스는 내부 정책을 사용해 어떤 키를 삭제할지 결정
- Noeviction
- 기본값
- 데이터가 가득 차더라고 임의로 데이터를 삭제하지 않고, 저장할 수 없다는 에러 반환
- 데이터가 가득 차더라도 캐시 내부적 판단으로 데이터를 삭제하는 것이 위험한 경우 사용
- LRU eviction(least recently used)
- 가장 최근에 사용하지 않은 데이터부터 삭제
- ss
- Valatile-lru : 만료시간이 설정된 키에 한해서 키를 삭제
- 삭제되면 안 되는 키는 TTL 설정을 지정하지 않으면 된다
- Alleys-lru : 모든 키에 한해서 키를 삭제
- LFU eviction(least frequently used)
- 가장 자주 사용되지 않은 데이터부터 삭제
- Valatile-lfu
- Alleys-lfu
- Random eviction
- 삭제될 키 값을 계산하지 않아도 된다는 장점 ( 부하를 줄일 )
- Volatile-ttl
캐시 스탬피드 ( stampede )
- 캐시 만료 시점에 여러 요청이 중복으로 데이터 조회 및 쓰기가 발생
- 이를 줄이기 위한 방안
- 적절한 만료 시간 설정
- 선 계산
- 키가 만료되기 전에 값을 미리 갱신
- 랜덤 확률로 데이터베이스에 접근하여 업데이트
- PER 알고리즘
- 확률적 조기 재계산 알고리즘
- 캐시값이 만료되기 전에 언제 데이터베이스에 접근해서 값을 읽어오면 되는지 최적으로 계산
세션 스토어로서의 레디스
세션
캐시와 세션의 차이
- 캐시
- 원본 데이터베이스의 완벽한 서브셋으로 동작
- 여러 애플리케이션에서 함께 사용할 만한 데이터
- 세션
- 필요한 경우만 데이터베이스에 저장, 이외는 휘발성
- 사용자 간 공유되지 않는 데이터