장난감 연구소
[캐시] 캐시 문제 해결 가이드 본문
캐시 관련 문제 방지 방법
이런 문제가 있는지 알게 되어 나중에 알아보기 위해 저장해놓습니다.
캐시 문제 해결 가이드 - DB 과부하 방지 실전 팁
대용량 트래픽 환경에서 캐시를 사용할 때 주의해야할 위험 상황과 예방법을 소개합니다.
toss.tech
GPT 응답
더보기
캐시 스탬피드(Cache Stampede)란?
캐시 스탬피드는 특정 캐시 키가 만료되었을 때 다수의 클라이언트 요청이 동시에 원본 데이터 소스(DB 등)에 몰리며 과부하가 발생하는 현상을 말합니다.
예시 상황:
- 인기 있는 데이터(예: 실시간 뉴스 헤드라인)가 캐시에 저장됨.
- 캐시 만료 시간(TTL)이 되어 해당 키가 캐시에서 사라짐.
- 동시에 수천, 수만 개의 요청이 들어오면, 전부 DB로 향하게 됨.
- DB 과부하 → 응답 지연 또는 장애 발생.
이게 바로 캐시 스탬피드 문제예요.
발생 원인
- 동시에 요청이 몰리는 핫 키(Hot Key) 존재
- TTL(만료 시간)이 동일하게 설정되어 만료 순간에 요청이 집중됨
- 백업 캐시 전략 없음 (캐시 미스 시 바로 DB 접근)
방지 방법
캐시 스탬피드를 막기 위해 여러 기법이 사용됩니다:
1. 캐시 만료 시간(TTL) 분산
- 모든 키에 같은 TTL을 주지 않고, **랜덤 지연(randomized expiration)**을 추가해서 한꺼번에 만료되지 않도록 함.
- int ttl = 60; // 60초 int jitter = new Random().nextInt(10); // 0~9초 랜덤 cache.set(key, value, ttl + jitter);
- 이렇게 하면 특정 시점에 몰리는 현상이 줄어듦.
2. 소프트 만료(Soft Expiration) / 백그라운드 갱신
- 캐시 만료 전 일정 기간을 "소프트 만료"로 두고,
- 첫 번째 요청자가 백그라운드에서 DB 갱신을 하도록 하고,
- 다른 요청자들은 이전 캐시 값을 계속 사용하게 하는 방식.
- 예: Guava Cache, Spring Cache에서 지원 가능.
3. 뮤텍스(Mutex) / 락(Lock) 사용
- 캐시에 값이 없을 때, 하나의 요청만 DB 조회하도록 락을 걸고, 다른 요청자는 기다리게 함.
- Redis SETNX(set if not exists) 같은 기능을 활용.
- 첫 번째 요청만 DB 조회 → 캐시에 반영
- 이후 요청은 캐시된 값 사용
4. Lazy Recalculation / 요청 직전 재계산
- 요청이 들어왔을 때 캐시가 만료됐다면,
- 만료 직후 DB에서 읽어오지 않고,
- 미리 준비된 값(backup cache, stale cache) 을 반환
- 동시에 백그라운드에서 새 값을 갱신
5. 캐시 프리로딩(Cache Warming)
- 캐시 만료 전에 미리 갱신해 놓는 방법.
- 배치 작업이나 백그라운드 스케줄러(Cron)로 자주 조회되는 데이터를 캐시에 주기적으로 넣음.
'개발 > DB' 카테고리의 다른 글
| [MySQL] 가까운 순 조회시 공간 인덱스 사용 (0) | 2025.07.17 |
|---|---|
| [DB/JPA] Index와 EntityGraph 적용 과정 정리 (0) | 2025.01.20 |