모든 데이터를 DB에만 넣으면 성능 문제가 생기고,
모든 데이터를 Redis에만 넣으면 장애 시 데이터가 날아간다.
데이터 성격에 맞는 저장소를 선택하는 것이 핵심이다.
저장소를 결정할 때 이 4가지를 먼저 물어본다.
1. 이 데이터가 사라져도 괜찮아?
2. 이 데이터가 얼마나 자주 바뀌어?
3. 이 데이터를 얼마나 빠르게 읽어야 해?
4. 이 데이터가 다른 데이터와 연관이 있어?
질문별 판단
사라지면 안 됨 → DB
사라져도 됨 → Redis
거의 안 바뀜 → DB
자주 바뀜 → Redis
느려도 됨 → DB
빠르게 읽어야 함 → Redis
JOIN이 필요함 → DB
독립적인 데이터 → Redis
| 데이터 유형 | 저장소 | 이유 |
|---|---|---|
| 유저 정보 | DB | 영구 보존 필요 |
| 게임 전적 | DB | 영구 보존 필요 |
| 로그인 세션 | Redis | 휘발성, 빠른 조회 |
| 방 정보 | Redis | 휘발성, 자주 변경 |
| 준비 상태 | Redis | 자주 변경 |
| 랭킹 | Redis + DB | Redis로 빠르게 조회, DB로 영구 보존 |
| 인증 토큰 | Redis | 만료 시간 관리 (TTL) |
| 분산락 | Redis | 빠른 처리, 자동 만료 |
읽기가 쓰기보다 많은 데이터에 적합한 패턴이다.
[읽기]
→ Redis 먼저 확인
→ 있으면 (Cache Hit) → Redis에서 바로 반환
→ 없으면 (Cache Miss) → DB에서 읽고 Redis에 저장 후 반환
[쓰기]
→ DB에 저장
→ Redis 캐시 삭제 (다음 읽기 때 DB에서 새로 읽도록)
장점
→ 구현이 단순
→ 실제 읽히는 데이터만 캐싱
→ Redis 장애 시 DB로 폴백 가능
단점
→ Cache Miss 시 DB 조회 발생
→ 캐시 삭제 타이밍 잘못되면 Stale Data (오래된 데이터) 제공
→ 처음 요청은 항상 느림
적합한 상황
→ 유저 정보 조회
→ 랭킹 조회
→ 읽기가 쓰기보다 압도적으로 많은 경우
쓰기 요청 시 DB와 Redis에 동시에 저장하는 패턴이다.
[쓰기]
→ DB에 저장
→ 동시에 Redis에도 저장
→ 항상 DB와 Redis가 동일한 상태 유지
[읽기]
→ Redis에서 바로 반환 (항상 최신 데이터)
장점
→ DB와 Redis 항상 일치 (정합성 보장)
→ Cache Miss 발생 안 함
→ 데이터 신뢰도 높음
단점
→ 쓰기 응답이 느려짐 (DB + Redis 둘 다 저장해야 하니까)
→ 읽히지 않는 데이터도 Redis에 캐싱됨
→ Redis 장애 시 쓰기 자체가 실패할 수 있음
적합한 상황
→ 결제, 포인트 등 정합성이 중요한 데이터
→ 읽기/쓰기 빈도가 비슷한 경우
데이터 성격에 따라 저장소를 완전히 나누는 패턴이다.
Redis 전용 데이터 → DB에 아예 안 씀
DB 전용 데이터 → Redis에 아예 안 씀
동기화 로직 자체가 없음
장점
→ 역할이 명확해서 관리 쉬움
→ 동기화 로직 불필요
→ 각 저장소 최적화 설정 가능
단점
→ Redis 장애 시 해당 기능 전체 불가
→ 데이터 성격 판단을 처음에 잘 해야 함
→ 나중에 구조 바꾸기 어려움
적합한 상황
→ 방 정보, 세션처럼 휘발성 데이터
→ 게임 진행 상태
→ TTL로 자동 삭제되는 임시 데이터
| Cache Aside | Write Through | 완전 분리 | |
|---|---|---|---|
| 정합성 | 낮음 | 높음 | 해당 없음 |
| 읽기 성능 | 높음 | 높음 | 높음 |
| 쓰기 성능 | 높음 | 낮음 | 높음 |
| 구현 복잡도 | 낮음 | 중간 | 낮음 |
| Redis 장애 영향 | 낮음 (DB 폴백) | 높음 | 높음 |
유저 정보 조회 → Cache Aside
→ 읽기가 압도적으로 많으니까
랭킹 업데이트 → Cache Aside
→ DB가 원본, Redis가 조회용
방 정보 / 세션 → 완전 분리
→ 휘발성이라 DB 테이블 자체가 없음
결제, 포인트 → Write Through
→ 정합성이 중요하니까
실수 1. 모든 걸 DB에 넣는다
→ 실시간 데이터도 DB에 넣으면 성능 병목 발생
실수 2. 모든 걸 Redis에 넣는다
→ Redis 장애 시 모든 데이터 유실
→ 중요한 데이터는 반드시 DB에
실수 3. Redis를 단순 캐시로만 생각한다
→ Sorted Set으로 랭킹 구현
→ TTL로 세션 자동 만료 관리
→ SETNX로 분산락 구현
→ Redis 자료구조를 잘 활용하면 DB 부하를 크게 줄일 수 있음
한 서비스 안에 세 패턴이 다 공존하는 경우가 대부분이다
데이터 성격마다 골라서 쓰는 것이 핵심사라지면 안 되는 것 → DB
빠르게 읽어야 하거나 자주 바뀌거나 만료가 있는 것 → Redis
애매하면 DB에 넣고 성능 문제 생기면 Redis 추가하는 게 안전