캐시는 성능이 아니라 복잡성이다
캐시는 “빠르게 해준다”가 아니라
상태를 하나 더 만든다는 결정이거든요.
1) 캐시를 넣는 순간 늘어나는 것들
A. 상태가 하나 더 생김
- DB 상태
- 캐시 상태 (부분 복제, 지연 반영)
→ 이제 정답이 두 개입니다.
B. 일관성 문제
- Write-through / Write-behind
- TTL 만료 타이밍
- 부분 무효화 / 전체 무효화
→ “언제 틀려도 괜찮은가?”를 정의해야 함
C. 장애 전파
- 캐시 장애 = DB 폭주
- 캐시 스탬피드
- 핫키 하나로 전체 시스템 흔들림
D. 디버깅 난이도 상승
- “로컬에서는 안 됨”
- “새로고침하면 됨”
- “조금 기다리면 됨”
→ 이 시점부터 재현 불가 버그가 됩니다.
2) 그래서 캐시는 언제 넣는 게 맞나
성능이 아니라 ‘비용’을 줄이기 위해 넣을 때만 의미 있습니다.
캐시가 합리적인 경우
- 동일 결과가 반복적으로 요청됨
- 약간의 지연/오차 허용 가능
- DB/외부 연계 호출 비용이 큼
- 무효화 규칙을 말로 설명할 수 있음
👉 설명 못 하면 넣지 말 것
3) 실무에서 가장 안전한 캐시 원칙
- 읽기 캐시부터
- TTL 짧게 시작
- 무효화 로직 최소화
- 캐시 미스가 기본 시나리오
- 캐시 장애 시 DB가 살아야 함
한 줄로:
캐시는 최적화가 아니라 부채다. 필요할 때만 진다.
4) Spring 기준으로 특히 위험한 패턴
- @Cacheable 남발
- 엔터티 통째로 캐싱
- 유스케이스 경계 무시
- 트랜잭션 안에서 캐시 갱신
이거 다 운영 지뢰입니다.
5) 르무엘님 문장, 더 날카롭게 쓰면
캐시는 시스템을 빠르게 만드는 기술이 아니라,
시스템을 이해하기 어렵게 만드는 선택이다.
또는 회고용으로는 이게 더 세죠.
캐시를 넣은 순간, 우리는 성능이 아니라 복잡성을 샀다.
'Spring & Backend' 카테고리의 다른 글
| 운영에서 살아남는 스프링 앱은 로그와 메트릭이 먼저다 (0) | 2026.02.02 |
|---|---|
| 빈 라이프사이클을 모르면 버그는 ‘느낌’으로만 잡는다 (0) | 2026.02.02 |
| 스프링은 확장에 강하다. 대신 초기 설계를 대충하면 고통도 같이 확장된다 (0) | 2026.02.02 |
| 스케일은 트래픽이 아니라 상태 관리에서 갈린다 (0) | 2026.02.02 |
| 백엔드는 보이지 않지만, 모든 장애는 거기서 시작한다 (0) | 2026.02.02 |
