티스토리 뷰
Spring Cache에서 @Cacheable, @CachePut, @CacheEvict의 차이점과 각각을 어떤 상황에서 사용하는 것이 적절한지 설명해주세요.
캐시(Cache)는 한 번 처리한 데이터를 임시 저장소(메모리)에 저장해두었다가, 똑같은 요청이 오면 복잡한 과정을 거치지 않고 즉시 내어주는 기술.
Spring Cache는 선언적 캐시 관리를 위한 여러 애노테이션을 제공. 각 애노테이션은 서로 다른 캐시 동작을 담당하며, 적절한 상황에서 사용해야 함.
@Cacheable : 가장 많이 쓰이는 데이터 조회용 어노테이션
동작 방식
캐시 확인: 메서드를 호출하기 전, 지정된 캐시 저장소에 동일한 Key값이 있는지 확인
Cache Hit: 값이 있다면 메서드를 실행하지 않고 저장된 값을 즉시 반환
Cache Miss: 값이 없다면 메서드를 직접 실행하여 DB에서 데이터를 가져온 뒤, 그 결과를 캐시에 저장하고 반환
어떤 상황에서 사용해야 할까?
게시글 상세 조회: 내용이 자주 바뀌지 않는데 조회는 빈번할 때
복잡한 계산: 결과 도출까지 시간이 오래 걸리는 연산 작업
@CachePut : 데이터 수정 시 캐시를 최신화하기 위해 사용
동작 방식
무조건 실행: @Cacheable과 달리, 캐시에 값이 있든 없든 항상 메서드 본문을 실행
캐시 갱신: 메서드가 반환한 최신 결과값을 지정된 Key에 덮어씌움
어떤 상황에서 사용해야 할까?
사용자 프로필 수정: DB에서 내 정보를 수정함과 동시에, 로그인 세션이나 캐시에 저장된 내 정보도 최신 데이터로 바꿔야 할 때
설정값 변경: 관리자가 시스템 설정값을 변경했을 때, 즉시 캐시에도 반영되어야 할 때
@CacheEvict : 더 이상 유효하지 않은 캐시를 삭제할 때 사용
동작 방식
캐시 제거: 메서드가 호출되면 지정된 Key에 해당하는 데이터를 캐시에서 삭제
옵션 활용: allEntries = true 옵션으로 캐시 전체 삭제도 가능
어떤 상황에서 사용해야 할까?
게시글 삭제: 게시글이 삭제되었는데 캐시에 남아있으면 안 되므로 해당 글 번호의 캐시를 제거
일괄 업데이트: 대규모 데이터 변경이 일어나서 기존 캐시들이 전부 부정확해졌을 때 allEntries로 전체 초기화
정리
| 구분 | @Cacheable | @CachePut | @CacheEvict |
| 주요 목적 | 캐시 조회 및 저장 (읽기) | 캐시 업데이트 (쓰기/수정) | 캐시 삭제 (삭제) |
| 메서드 실행 여부 | 캐시가 없으면 실행 | 항상 실행 | 항상 실행 |
| 캐시 영향 | 결과값을 저장함 | 결과값을 저장(갱신)함 | 데이터를 삭제함 |
로컬 캐시와 분산 캐시의 개념 차이와 각각의 장단점, 그리고 실무에서 어떤 기준으로 선택해야 하는지 설명해주세요.
로컬 캐시(Local Cache)
애플리케이션과 같은 JVM 메모리 공간에서 동작하는 캐시
해당 서버만 이 데이터에 접근할 수 있음
대표 기술: Ehcache, Caffeine Cache 등
장점
속도가 압도적: 네트워크를 타지 않고 서버 내부 메모리에서 바로 꺼내오기 때문에 응답 시간이 거의 0에 수렴함
구성의 단순함: 별도의 캐시 서버를 구축할 필요가 없어 설정이 간단
단점
데이터 불일치: 서버가 여러 대일 경우, 1번 서버의 데이터는 수정됐는데 2번 서버는 옛날 데이터를 들고 있을 수 있음
메모리 부족: 서버 자체의 메모리를 사용하므로, 데이터가 너무 많아지면 서비스 운영에 지장을 줄 수 있음
분산 캐시(Distributed Cache)
여러 대의 서버가 공통으로 접속하는 별도의 캐시 전용 서버를 두는 방식
대표 기술: Redis, Memcached
장점
데이터 일관성: 어떤 서버에서 접속하든 항상 최신의 동일한 데이터를 볼 수 있음
확장성: 캐시 데이터가 많아지면 캐시 서버만 따로 늘리면 되므로 본체 서버의 자원을 아낄 수 있음
단점
상대적으로 느림: 네트워크를 통해 데이터를 주고받아야 하므로 로컬 캐시보다는 느림
관리 비용: 별도의 Redis 서버를 띄우고 관리해야 하는 운영 부담이 생김

실무에서 어떤 기준으로 선택해야 할까?
로컬 캐시가 유리한 경우
서버가 단일 서버(1대)일 때
데이터가 거의 변하지 않을 때
네트워크 통신 시간(밀리초 단위)조차 허용되지 않는 빠른 응답 속도가 필요할 때
비용 절감이 중요할 때
분산 캐시가 유리한 경우
서버가 여러 대(Scale-out)일 때
데이터 일관성이 매우 중요할 때
캐싱할 데이터 양이 방대할 때
데이터의 영속성이 필요할 때
하이브리드 전략 (L1/L2 Cache)
L1 캐시 (로컬): 아주 자주 조회되는 데이터는 로컬에 두어 네트워크 비용을 아예 없앰
L2 캐시 (분산): 로컬에 없는 데이터는 Redis에서 찾아옴
