본문 바로가기
Java & Spring

Spring Cache 고급편: Caffeine + Redis 하이브리드 캐시 아키텍처 실전 가이드

by yamoojin83 2025. 12. 11.

Spring Cache 고급편: Caffeine + Redis 하이브리드 캐시 아키텍처 실전 가이드

Spring Boot에서 API 성능을 높이는 가장 간단한 방법은 캐싱입니다. 하지만 단일 캐시(Caffeine 또는 Redis)만 사용하는 구조는 트래픽 증가나 장애 상황에서 한계가 발생합니다. 이번 글에서는 Caffeine(로컬 메모리 캐시)Redis(분산 캐시)를 함께 사용하는 하이브리드 캐시 아키텍처를 구성하는 방법을 다룹니다.

 

전체 아키텍처 다이어그램

1) 단일 캐시 구조의 한계

Caffeine만 사용하는 경우:

  • 속도는 빠르지만 서버 인스턴스마다 캐시가 분리됨
  • 스케일아웃 시 캐시 일관성 문제 발생

Redis만 사용하는 경우:

  • 일관성은 좋지만 네트워크 호출 비용이 존재
  • TPS가 높은 API에서는 Redis가 병목이 되기 쉬움

2) 하이브리드 캐시 아키텍처 등장

“읽기”는 로컬(Caffeine),
“갱신/삭제”는 Redis Pub/Sub으로 동기화
하는 방식입니다.

요청 흐름:
Client → Spring Cache → (Hit: Caffeine) or (Miss: Redis 조회) → DB

이 구조의 장점은 다음과 같습니다:

  • 최고 속도(Caffeine) + 일관성(Redis)을 동시 확보
  • Redis 장애 시에도 로컬 캐시로 읽기 기능 유지 가능
  • 대규모 트래픽에서 비용 대비 성능이 가장 뛰어난 구조

3) Gradle 의존성 추가

implementation 'org.springframework.boot:spring-boot-starter-cache'
implementation 'com.github.ben-manes.caffeine:caffeine'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'

4) Caffeine + Redis 캐시 설정

@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    public Caffeine<Object, Object> caffeineSpec() {
        return Caffeine.newBuilder()
                .maximumSize(10_000)
                .expireAfterWrite(10, TimeUnit.MINUTES);
    }

    @Bean
    public RedisCacheConfiguration redisCacheConfiguration() {
        return RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(10))
                .disableCachingNullValues();
    }
}

Caffeine local cache detail

 

5) 캐시 동기화를 위한 Redis Pub/Sub

데이터가 변경되면 Redis에 invalidate 메시지를 발행합니다. 각 서버 인스턴스는 이를 구독하고 Caffeine 캐시를 삭제합니다.

@Component
@RequiredArgsConstructor
public class CacheInvalidator {

    private final StringRedisTemplate redisTemplate;

    public void evict(String cacheName, String key) {
        redisTemplate.convertAndSend("cache:invalidate", cacheName + "::" + key);
    }
}

Redis Pub/Sub cache invalidation

6) TTL 전략

TTL은 보통 다음 기준으로 설정합니다:

  • 읽기 빈도가 높은 API: 1~10분
  • 변경이 자주 일어나는 API: 수 초~1분
  • 로그성 데이터: 30분~1시간

7) 어떤 API에 적용해야 하나?

적합

  • 조회가 전체 트래픽의 90% 이상인 API
  • 변경이 드문 정보: 상품 정보, 공지, 카테고리 목록
  • DB 또는 외부 API 호출 비용이 큰 경우

부적합

  • 요청마다 결과가 크게 달라지는 API
  • 인증·보안 관련 API

8) 운영 단계에서 꼭 필요한 모니터링

모니터링해야 할 지표는 다음과 같습니다:

  • Caffeine hit ratio
  • Redis latency
  • Pub/Sub 장애
  • DB fallback 빈도

이 지표만 정확히 추적해도 캐시 운영 안정성이 크게 올라갑니다.

마무리

Caffeine + Redis 하이브리드 캐시는 "속도와 일관성"을 모두 잡는 가장 실용적 구조입니다. Spring Boot 서비스의 응답 시간을 개선하고 싶다면 반드시 고려해볼 만한 아키텍처입니다.