백엔드 캐시 전략에서 자주 비교되는 @CacheEvict / @Cacheable 방식과 TTL(Time To Live) 방식은 캐시의 무효화 타이밍과 제어 방식이 다릅니다. 아래에 비교와 함께 적용 시 고려사항을 정리해 드리겠습니다.


---

✅ 1. @Cacheable / @CacheEvict 방식

🔹 개념

@Cacheable: 메서드 실행 결과를 캐시에 저장 (처음만 실행, 이후 캐시 사용)

@CacheEvict: 데이터 변경 시 캐시에서 제거(무효화)


🔹 특징

수동 무효화: 데이터가 변경되는 시점에서 명시적으로 캐시를 삭제 (@CacheEvict)

정확한 무효화 가능: 데이터 변경과 캐시 무효화 타이밍을 맞출 수 있음

적절한 시점에 무효화가 되면 최신성을 유지하면서 성능을 높일 수 있음


🔹 적용 예시

@Cacheable(value = "user", key = "#userId")
public User getUser(Long userId) {
    return userRepository.findById(userId);
}

@CacheEvict(value = "user", key = "#user.id")
public void updateUser(User user) {
    userRepository.save(user);
}

🔹 고려사항

캐시 일관성 유지가 중요할 때 적합

코드 레벨에서 무효화를 직접 제어해야 하므로 로직이 복잡해질 수 있음

잘못된 무효화 처리 시 오래된 데이터가 유지될 수 있음



---

✅ 2. TTL (Time To Live) 방식

🔹 개념

캐시에 저장된 데이터에 **유효 시간(예: 10분)**을 설정

TTL이 지나면 자동으로 만료 → 다음 요청 시 DB에서 재조회 후 재캐싱


🔹 특징

자동 무효화: 별도 @CacheEvict 없이 일정 시간 후 캐시가 제거됨

구현이 단순하며 어떤 변경이 있어도 일정 시간 후에는 최신화됨

자주 변경되는 데이터에는 적합하지 않을 수 있음


🔹 적용 예시

Redis, Caffeine 등 외부 캐시에서 TTL 설정


@Bean
public CacheManager cacheManager() {
    Caffeine<Object, Object> caffeine = Caffeine.newBuilder()
        .expireAfterWrite(10, TimeUnit.MINUTES);
    return new CaffeineCacheManager("user");
}

🔹 고려사항

TTL이 너무 짧으면 캐시 효과가 낮고 DB 부하↑

TTL이 너무 길면 오래된 데이터가 유지됨

실시간 동기화가 중요한 서비스에는 부적합할 수 있음



---

📊 비교 요약

항목 @Cacheable / @CacheEvict TTL(Time To Live)

무효화 방식 수동 무효화 (@CacheEvict 호출) 자동 만료(시간 기반)
최신성 보장 높음 (정확한 타이밍) TTL 내에선 보장 안됨
복잡성 비교적 높음 (코드 관리 필요) 낮음 (설정만 하면 됨)
사용 시점 데이터 정확성 중요 시 성능 우선, 변화 적은 데이터
단점 관리 복잡, 실수 시 일관성 오류 TTL 오차로 데이터 신선도 저하



---

🧠 실무 적용 팁

정확한 캐시 무효화가 필요한 경우: @CacheEvict 사용 (예: 주문 상태, 결제 내역)

조회 빈도가 높고 갱신이 적은 데이터: TTL 방식 (예: 공지사항, 코드 테이블)

LIST

+ Recent posts