GW LABS

Spring Rest API 캐싱전략 완벽 가이드: @Cacheable과 CacheManager 활용법 본문

Programming/Java

Spring Rest API 캐싱전략 완벽 가이드: @Cacheable과 CacheManager 활용법

GeonWoo Kim 2025. 8. 18. 15:55

Spring Rest API 캐싱전략 완벽 가이드: @Cacheable과 CacheManager 활용법

서론

Rest API 서버를 운영하다 보면 가장 큰 고민 중 하나는 성능과 응답 속도입니다. 특히 조회 요청이 빈번한 API의 경우, 매번 DB를 조회하는 것은 서버 부담을 크게 증가시킵니다. 이를 효율적으로 해결하는 방법이 바로 캐싱(Caching)입니다.
Spring은 @CacheableCacheManager를 통해 강력하면서도 유연한 캐싱 기능을 제공하고 있으며, 상황에 맞는 캐싱 전략을 적용하면 성능 최적화 효과를 극대화할 수 있습니다.

이번 포스팅에서는 Spring Rest API 캐싱전략, CacheManager 사용법, @Cacheable 활용법을 중심으로 실무 적용 방법을 정리하겠습니다.


본론

1. Spring Rest API 캐싱전략

Spring에서 캐싱은 크게 다음과 같은 전략으로 나눌 수 있습니다.

  • 읽기 중심 API 캐싱: 자주 조회되지만 데이터 변경이 드문 API 응답을 캐싱.
  • 조건부 캐싱: 특정 조건(예: 파라미터 값, 사용자 권한)에 따라 캐싱 여부 결정.
  • TTL(Time-to-Live) 전략: 데이터 유효기간을 설정하여 일정 시간 후 자동으로 캐시 무효화.
  • 분산 캐싱: Redis, Hazelcast 등 외부 캐시 서버를 사용하여 다중 서버 환경에서도 일관된 캐시 유지.

캐싱 전략 선택 시 고려해야 할 요소는 다음과 같습니다.

  • 데이터의 변경 주기
  • 실시간성이 중요한지 여부
  • API 호출 빈도
  • 인프라 구성(단일 서버 vs 다중 서버)

2. CacheManager 사용법

Spring은 CacheManager를 통해 다양한 캐시 구현체(EhCache, Redis, Caffeine 등)를 추상화합니다.

예제: Caffeine Cache 설정

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

import java.util.concurrent.TimeUnit;

@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    public CacheManager cacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager("users", "products");
        cacheManager.setCaffeine(
                Caffeine.newBuilder()
                        .expireAfterWrite(10, TimeUnit.MINUTES)
                        .maximumSize(1000)
        );
        return cacheManager;
    }
}

위 코드에서는 Caffeine 캐시를 사용하며, users, products 캐시 영역을 정의했습니다. TTL은 10분, 최대 캐시 사이즈는 1000개로 설정되어 있습니다.

3. @Cacheable 사용법

@Cacheable은 메서드 실행 결과를 캐싱하고, 동일한 파라미터로 호출 시 캐시된 결과를 반환합니다.

기본 사용법

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

@Service
public class UserService {

    @Cacheable(value = "users", key = "#userId")
    public User getUserById(Long userId) {
        simulateSlowService();
        return new User(userId, "User_" + userId);
    }

    private void simulateSlowService() {
        try {
            Thread.sleep(3000); // DB 조회 대기 시간 가정
        } catch (InterruptedException e) {
            throw new IllegalStateException(e);
        }
    }
}

주요 속성

  • value: 캐시 이름 지정 (CacheManager에서 관리)
  • key: 캐시 키 정의 (SpEL 사용 가능)
  • condition: 조건부 캐싱 여부 지정
  • unless: 결과에 따라 캐싱 제외

조건부 캐싱 예시

@Cacheable(value = "products", key = "#id", condition = "#id > 10")
public Product getProduct(Long id) {
    return new Product(id, "Product_" + id);
}

→ ID가 10보다 큰 경우에만 캐싱.


결론

Spring Rest API에서 캐싱은 단순한 성능 최적화 이상의 의미를 가집니다. 캐싱 전략을 올바르게 적용하면 DB 부하 감소, 응답 속도 향상, 서비스 안정성 강화라는 세 마리 토끼를 동시에 잡을 수 있습니다.

정리하자면,

  • CacheManager로 다양한 캐시 구현체를 통합 관리할 수 있고,
  • @Cacheable을 통해 선언형 캐싱을 손쉽게 적용할 수 있으며,
  • 상황별 캐싱 전략(TTL, 조건부 캐싱, 분산 캐싱)을 병행하면 실무에서 강력한 성능 최적화를 이끌어낼 수 있습니다.

👉 효율적인 캐싱 전략은 API 성능을 한 단계 끌어올리는 핵심 무기입니다.

Comments