_z_z_
8월_4주차. Cache 어노테이션의 차이점, 로컬 캐시와 분산캐시 본문
더보기
Q1. Spring Cache에서 @Cacheable, @CachePut, @CacheEvict의 차이점과 각각을 어떤 상황에서 사용하는 것이 적절한지 설명해주세요.
Q2. 로컬 캐시와 분산 캐시의 개념 차이와 각각의 장단점, 그리고 실무에서 어떤 기준으로 선택해야 하는지 설명해주세요
1. @Cacheable / @CachePut / @CacheEvict 차이와 쓰임새
- @Cacheable
- 동작: 캐시에 있으면 메서드 호출 생략 후 캐시값 반환, 없으면 메서드 실행
- → 결과를 캐시에 저장
- 조회성api, 변경이 드문 데이터. ex) 책 상세, 인기 랭킹 스냅샷
- 기본적으로 메서드 파라미터로 키를 만든다. unless, condition, key로 제어.
- 동시성이 많은 경우 sync=true로 캐시 스탬피드 완화
- @CachePut
- 동작: 항상 메서드를 실행하고, 결과를 캐시에 갱신, 반환값은 메서드 결과
- 업데이트 후 캐시를 최신화해야할 때. ex) 리뷰 수정/생성 직후 해당 리뷰 캐시 동기화
- @Cacheable과 다른 점은 “미스여도 스킵 없음”, 키 계산이 @Cacheable과 일치해야 함(같은 cacheNames, 같은 key 식)
- @CacheEvict
- 동작: 캐시 무효화. allEntries=true 면 캐시 이름 공간 전체 삭제
- 원본 데이터가 바뀌어 기존 캐시가 더는 유효하지 않을 때. ex) 리뷰/댓글 수 변경 후 인기 랭킹 리스트 캐시 제거
- 트랜잭션 안에서 beforeInvocation=true(예외나도 먼저 지움) 여부를 의도대로 설정. 보통은 기본 값(커밋 후)으로 둠
2. 로컬 캐시 vs 분산 캐시
- 로컬캐시 : 애플리케이션 인스턴스 메모리에 저장. 인스턴스마다 캐시가 따로 존재
- 분산캐시: 외부 캐시 서버/클러스터에 저장(보통 redis, hazelcast, memcached) 여러 인스턴스가 같은 캐시를 공유
| 구분 | 로컬 캐시(Caffeine) | 분산 캐시(Redis) |
| 지연시간 | 아주 낮음(메모리 접근) | 네트워크 왕복 → 낮지만 로컬보다 높음 |
| 일관성 | 인스턴스 간 불일치 가능 | 인스턴스 간 공유, 일관성 좋음 |
| 확장성 | 인스턴스 수 x 메모리만큼 증가(복제) | 중앙집중 관리, 용량/스케일 아웃 용이 |
| 장애 영향 | 앱과 운영공동체(앱 죽으면 캐시도 사라짐) | 단일 장애 지점(SPOF) 관리 필요(클러스터링/복제) |
| 운영 복잡도 | 낮음(앱 의존) | 높음(운영, 모니터링, 보안, 비용) |
| 일관성 제어 | 어려움(무효화 브로드캐스트 필요) | 상대적으로 쉬움(한 곳에서 무효화) |
| 비용 | 추가 인프라 없음 | 있음(서버/매니지드 서비스 비용) |
실무 선택 기준
- 인스턴스가 여러 대인가? 오토스케일링/블루그린 배포?
- 다중 인스턴스, 트래픽 급등 → 분산 캐시 선호 (일관성/공유 필요)
- 단일 인스턴스(내부 툴, 관리자 콘솔) → 로컬 캐시로 충분
- 데이터 신선도/일관성 요구가 높은가?
- 인기 랭킹, 재고 수량 등 공유 일관성 중요 → 분산 캐시
- 프로필 썸네일 URL, 잘 변하지 않는 마스터 데이터 → 로컬 캐시 ok
- 지연시간 민감도
- 마이크로초급 응답 필요 & 데이터가 인스턴스-로컬에만 의미 → 로컬
- 수 ms 증가는 허용 & 다중 인스턴스 공유 필요 → 분산
- 데이터 크기/TTL/갱신 패턴
- 작은 객체, 짧은 TTL, 읽기 위주 → 로컬도 좋음
- 큰 목록/집계 결과를 여러 인스턴스가 공유해야 → 분산
- 운영 복잡도/비용 허용도
- Redis운영(복제/감시/백업/보안) 부담 가능 → 분산
- 초기 단순성, 속도 우선 → 로컬로 시작하고 히트가 높아지고 인스턴스가 늘면 혼합 전략 고려
추천 패턴
- 하이브리드(2-레벨) 캐시:미스 시 Redis 조회 → 로컬에 단기 저장. 지연, 트래픽 감소
- 단, 무효화 설계가 중요(예: Redis Pub/Sub로 로컬 캐시 인밸리데이션 브로드캐스트)
- 1차 로컬(Caffeine) @+ 2차 분산(Redis)
- Cache-Aside(캐시 어사이드)쓰기: DB 업데이트 → 캐시 삭제(@CacheEvict) 또는 최신값 갱신(@CachePut)
- 대량 변경/배치 후에는 목록 캐시 전체 무효화가 안전
- 읽기: 캐시 확인 → 미스면 DB → 캐시에 넣음
- 키 네임스페이스/버저닝
- 버전 접두사로 대규모 무효화를 간단히
- TTL + 스프레드 재계산
- 동일시점 만료로 인한 스파이크 방지: TTL에 jitter(랜덤 ±%) 적용
- 직렬화/압축(분산 캐시)
- Redis 사용 시 버전 호환 직렬화(Kryo/JSON), 압축(LZ4 등) 검토
'쪼드잇 > 위클리페이퍼' 카테고리의 다른 글
| 8월_5주차. TCP/IP와 OSI 모델, 전송 계층에서의 TCP와 UDP (3) | 2025.09.01 |
|---|---|
| 8월_3주차. Race Condition과 해결 전략, 비동기 환경에서의 MDC 전달 (6) | 2025.08.18 |
| 8월_2주차. Spring 주요 보안공격과 대응전략, JWT의 구조와 구성 요소 (6) | 2025.08.11 |
| 8월_1주차. 세션과 토큰 기반 인증, QAuth 2.0 (3) | 2025.08.03 |
| 7월_1주차. AWS RDS와 EC2, GitHub 트리거 (5) | 2025.06.30 |