캐시 사용중 발생할 수 있는 문제와 해결전략
1. Thundering herd / Cache Stampede 문제
1-1. 문제 개요
캐시가 만료되거나 삭제되었을 때, 동시에 많은 요청이 캐시 미스로 인해 동일한 데이터베이스나 백엔드 서비스에 동시에 요청을 보내는 현상입니다. Thundering herd와 Cache Stampede는 본질적으로 동일한 문제를 가리키며, 캐시 만료 시점에 대량의 요청이 동시에 캐시 재생성을 시도하면서 시스템에 과부하를 일으킵니다.
1-2. 원인
- 캐시 키가 동시에 만료되거나 삭제됨
- 캐시 미스 발생 시 모든 요청이 동일한 데이터 소스로 직접 접근
- 동시성 제어 메커니즘이 없어 여러 요청이 중복 작업 수행
- 인기 있는 캐시 키가 동시에 만료되는 경우
- 캐시 재생성 비용이 높은 작업(복잡한 쿼리, 외부 API 호출 등)일 경우
1-3. 해결전략
- Lock 메커니즘: 캐시 미스 시 하나의 요청만 데이터 소스에 접근하도록 분산 락 사용
- Single Flight Pattern: 동일한 키에 대한 재생성 요청을 하나로 묶어 처리
- Probabilistic Early Expiration: 캐시 만료 시간 전에 확률적으로 조기 만료하여 부하 분산
- Cache Warming / Background Refresh: 캐시 만료 전 미리 데이터를 갱신하거나 백그라운드에서 갱신하여 만료 시점의 부하 분산
- Stale-While-Revalidate: 만료된 캐시를 즉시 반환하면서 백그라운드에서 갱신
- Exponential Backoff: 캐시 미스 시 재시도 간격을 점진적으로 증가시켜 부하 분산
- Circuit Breaker: 연속적인 실패 시 일정 시간 캐시 재생성 시도를 차단
2. Cache Penetration (캐시 관통)
2-1. 문제 개요
존재하지 않는 데이터에 대한 요청이 캐시를 우회하여 데이터베이스에 직접 접근하는 현상입니다. 특히 악의적인 공격이나 잘못된 요청 패턴으로 인해 발생할 수 있습니다.
2-2. 원인
- 존재하지 않는 키에 대한 반복적인 요청
- 캐시에 저장되지 않은 데이터에 대한 접근
- Null 값도 캐시에 저장하지 않는 경우
2-3. 해결전략
- Null Object Caching: 존재하지 않는 데이터도 짧은 시간 동안 캐시에 저장하여 반복 요청 방지
- Bloom Filter: 데이터 존재 여부를 사전에 필터링하여 불필요한 데이터베이스 접근 차단
- Rate Limiting: 동일한 키에 대한 과도한 요청을 제한
- Input Validation: 요청 데이터의 유효성을 사전에 검증
3. Cache Avalanche (캐시 붕괴)
3-1. 문제 개요
대량의 캐시 키가 동시에 만료되거나 캐시 서버가 다운되어, 모든 요청이 데이터베이스로 몰리면서 시스템이 마비되는 현상입니다.
3-2. 원인
- 캐시 서버 장애로 인한 전체 캐시 손실
- 동일한 TTL(Time To Live)을 가진 많은 키들이 동시에 만료
- 캐시 서버 재시작이나 메모리 부족으로 인한 캐시 초기화
3-3. 해결전략
- TTL 분산: 캐시 만료 시간에 랜덤한 오프셋을 추가하여 동시 만료 방지
- Multi-level Caching: 여러 단계의 캐시 계층을 구성하여 한 단계 실패 시 다른 단계 활용
- Cache Replication: 여러 캐시 서버에 복제하여 단일 장애점 제거
- Graceful Degradation: 캐시 실패 시 제한된 기능으로 서비스 지속 제공
4. Cache Invalidation 문제
4-1. 문제 개요
원본 데이터가 변경되었을 때 캐시를 적절히 갱신하지 못하여, 오래된 데이터가 계속 제공되는 문제입니다.
4-2. 원인
- 데이터 변경 시 캐시 무효화 로직 누락
- 분산 환경에서 일부 캐시만 무효화되는 경우
- 복잡한 데이터 관계로 인한 연관 캐시 무효화 실패
4-3. 해결전략
- Write-Through Cache: 데이터 변경 시 캐시와 데이터베이스를 동시에 업데이트
- Event-Driven Invalidation: 데이터 변경 이벤트를 구독하여 관련 캐시 자동 무효화
- Version-based Caching: 캐시 키에 버전을 포함하여 데이터 변경 시 자동으로 새 버전 사용
- TTL 기반 갱신: 적절한 TTL 설정으로 일정 시간 후 자동 갱신
5. Hot Key 문제
5-1. 문제 개요
특정 캐시 키에 과도한 트래픽이 집중되어, 해당 키를 저장한 캐시 서버에 부하가 집중되는 현상입니다.
5-2. 원인
- 인기 있는 데이터가 단일 캐시 키로 저장됨
- 캐시 분산 전략이 키 기반 해싱만 사용하는 경우
- 특정 이벤트나 트렌드로 인한 갑작스러운 트래픽 증가
5-3. 해결전략
- Key Sharding: 핫 키를 여러 개의 키로 분할하여 부하 분산
- Local Cache: 애플리케이션 레벨의 로컬 캐시를 추가하여 원격 캐시 부하 감소
- Read Replication: 읽기 전용 캐시 복제본을 여러 개 생성
- Pre-computation: 인기 데이터를 미리 계산하여 여러 키에 분산 저장
6. Cache Coherency 문제
6-1. 문제 개요
여러 캐시 인스턴스나 계층 간에 동일한 데이터의 일관성이 유지되지 않는 문제입니다.
6-2. 원인
- 분산 캐시 환경에서 일부만 업데이트됨
- 캐시 계층 간 동기화 메커니즘 부재
- 네트워크 지연이나 장애로 인한 동기화 실패
6-3. 해결전략
- Cache-aside Pattern: 애플리케이션에서 캐시와 데이터베이스 일관성 관리
- Write-Behind Caching: 비동기적으로 캐시를 업데이트하되, 일관성 보장 메커니즘 포함
- Consistent Hashing: 캐시 노드 추가/제거 시에도 일관성 유지
- Eventual Consistency: 완전한 일관성 대신 최종 일관성을 보장하는 전략 채택