Spring Boot · 2026-05-03

Spring Boot 캐시 자동 만료(TTL) 전략 구현

Spring Boot에서 캐시 자동 만료(TTL) 개념과 Redis 및 로컬 캐시 적용 예제를 코드 중심으로 설명하는 실무용 자료

작성일 : 2026-05-03 ㆍ 작성자 : 관리자
post
목차

개요

서비스 성능을 위해 캐시를 도입할 때 중요한 요소 중 하나는 데이터의 유효 기간을 관리하는 방식이다. TTL(Time To Live)은 캐시 항목의 수명을 자동으로 관리한다. 여기서는 Spring Boot 환경에서 Redis와 로컬 캐시(Caffeine 등)를 대상으로 TTL 전략을 설계하고 구현하는 방법을 단계별로 설명한다. 초보자도 이해하기 쉽도록 개념과 코드 예제를 함께 제공한다.

TTL의 필요성

캐시를 무한히 보관하면 오래된 데이터로 인해 일관성이 깨질 수 있다. 반대로 너무 짧게 설정하면 캐시 히트율이 떨어진다. 따라서 다음과 같은 이유로 TTL 전략이 필요하다.

  • 데이터 신선도 유지
  • 메모리 사용량 제어
  • 자동 만료로 수동 정리 부담 감소

전략 설계 요소

TTL 전략은 단일 설정으로 끝나지 않는다. 서비스 특성에 따라 조합을 사용한다.

  • 기본 TTL: 모든 캐시에 적용되는 기본 만료 시간
  • 퍼-캐시 TTL: 중요한 캐시와 덜 중요한 캐시에 다른 TTL 적용
  • 수동 무효화: 데이터 변경 시 즉시 캐시 비우기
  • 계층적 캐시: 로컬 캐시와 Redis를 함께 사용하는 경우 각 계층별 TTL 조정

Spring Boot에서 Redis TTL 설정

Spring Data Redis의 RedisCacheManager를 사용하면 캐시별 TTL을 쉽게 설정할 수 있다. 아래 예제는 기본 TTL과 캐시별 TTL을 함께 설정하는 방법을 보여준다.

RedisCacheManager 설정 예제

package com.example.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class RedisCacheConfig {

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        RedisCacheConfiguration defaultConfig = RedisCacheConfiguration
                .defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(10));

        Map<String, RedisCacheConfiguration> cacheConfigurations = new HashMap<>();
        cacheConfigurations.put("short", defaultConfig.entryTtl(Duration.ofSeconds(30)));
        cacheConfigurations.put("long", defaultConfig.entryTtl(Duration.ofHours(6)));

        return RedisCacheManager.builder(redisConnectionFactory)
                .cacheDefaults(defaultConfig)
                .withInitialCacheConfigurations(cacheConfigurations)
                .build();
    }
}

위 설정에서 defaultConfig는 기본 TTL을 10분으로 정한다. 캐시 이름이 "short" 또는 "long"이면 각각 별도 TTL을 사용한다. 캐시 이름은 @Cacheable에서 사용하는 cacheNames와 일치해야 한다.

로컬 캐시(Caffeine)에서 TTL 적용

로컬 캐시는 메모리 기반으로 매우 빠르다. Caffeine을 쓰면 expireAfterWrite 또는 expireAfterAccess로 TTL을 설정할 수 있다.

CaffeineCacheManager 설정 예

package com.example.config;

import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.cache.caffeine.CaffeineCacheManager;

import java.util.concurrent.TimeUnit;

@Configuration
public class CaffeineConfig {

    @Bean
    public CaffeineCacheManager caffeineCacheManager() {
        CaffeineCacheManager cm = new CaffeineCacheManager("defaultCache");
        cm.setCaffeine(Caffeine.newBuilder()
                .expireAfterWrite(10, TimeUnit.MINUTES)
                .maximumSize(10_000));
        return cm;
    }
}

로컬 캐시는 네트워크 호출을 줄여준다. Redis와 함께 쓰는 경우 로컬 캐시는 짧은 TTL, Redis는 비교적 긴 TTL을 두는 것이 일반적이다.

서비스 레이어에서 캐시 사용 예

서비스 메서드에 @Cacheable을 붙이면 Spring이 자동으로 캐시를 관리한다. 캐시 무효화는 @CacheEvict로 처리한다.

package com.example.service;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Cacheable(cacheNames = "users", key = "#id")
    public User findById(Long id) {
        // DB 조회 로직
        return userRepository.findById(id).orElse(null);
    }

    @CacheEvict(cacheNames = "users", key = "#user.id")
    public void update(User user) {
        // DB 업데이트 로직
        userRepository.save(user);
    }
}

운영에서 고려할 점

  • TTL은 데이터 특성에 맞춰 설계한다. 실시간성이 강한 데이터는 짧은 TTL, 변경이 적은 데이터는 긴 TTL 사용
  • 캐시 키 정책을 일관되게 관리한다. 키 충돌은 의도치 않은 데이터 반환을 초래한다
  • 데이터 직렬화 방식(RedisSerializer)을 확인해 성능과 호환성을 확보한다
  • 모니터링을 통해 캐시 히트율과 메모리 사용량을 점검한다

요약

TTL은 캐시 일관성과 자원 관리를 위해 필수적인 설정이다. Spring Boot에서는 RedisCacheManager나 CaffeineCacheManager를 통해 손쉽게 TTL을 적용할 수 있다. 기본 TTL과 캐시별 TTL을 조합하고, 중요한 업데이트는 @CacheEvict로 즉시 반영하면 안정적인 캐싱 전략을 운영할 수 있다. 본문에서 제시한 설정 예제는 spring cache ttl 설정, redis ttl spring boot, cache expiration spring boot 같은 키워드와 함께 실무에 바로 적용 가능한 구조를 제시한다.

spring cache ttl 설정 redis ttl spring boot cache expiration spring boot spring cache redis cache ttl 설정 spring boot caching caffeine ttl