우당탕탕

Caffeine Cache (로컬 캐시, 카페인 캐시)란? 본문

언어/Java

Caffeine Cache (로컬 캐시, 카페인 캐시)란?

모찌모찝 2025. 4. 18. 18:00
Caffeine Cache (로컬 캐시, 카페인 캐시)란? 

카페인 캐시 (Caffeine Cache)란?

카페인 캐시는 Java8 이상에서 동작하는 고성능 인메모리(Local) 캐싱 라이브러리입니다. 스프링의 공식 지원 덕분에 손쉽게 연동이 가능하며, 서버 메모리(RAM)에서 데이터를 즉시 읽고 쓰기 때문에 네트워크 IO가 없이 빠른 응답속도를 자랑합니다.

SpringBoot

특징

카페인 캐시의 특징으로는 네트워크 트래픽 없이 서버 메모리에서 데이터를 접근해서 성능이 빠르고, Window TinyLFU 알고리즘을 사용하여 자주 사용하거나 최근 사용한 데이터 위주로 관리가 됩니다.(최적화된 캐시 정책) 또한 용량, 시간, 참조 기반의 다양한 캐시 만료옵션을 제공하며, application.yml 또는 Config를 통해 간편하게 적용이 가능합니다.

흔하게 알고있는 레디스 캐시(Redis Cache)와 카페인 캐시(Caffeine Cache)는 각각 언제 사용해야 할까요?

레디스 캐시와 카페인 캐시의 비교

항목 카페인 캐시 ( Caffeine Cache )  레디스 캐시 ( Redis Cache )
저장 위치 서버 내부 메모리(로컬) 외부 서버(분산, 글로벌)
접근 속도 Redis보다 빠름 (네트워크 없음) 빠름 (네트워크 필요)
데이터 공유 서버 간 공유 불가 여러 서버에서 데이터 공유 가능
확장성 서버 추가 시 캐시 일관성 깨질 수 있음 서버 추가해도 데이터 일관성 유지
장애 영향 서버 재시작 시 캐시 모두 소멸 Redis 장애 시 전체 캐시 영향
운영/비용 별도 비용 없음(무료, 내장) 별도 서버 운영/비용 발생
활용 예시 인기글, 랭킹, 조회수 등 세션, 토큰, 대규모 공용 데이터


카페인 캐시가 유리한 상황

- 단일 서버, 혹은 서버별로 데이터가 달라도 크게 상관이 없는 서비스
- DB 트래픽을 극적으로 줄이고, 응답속도를 극한까지 올리고 싶을 때 사용
- 인기글, 실시간 랭킹 등 자주 조회되는 글과 같은 읽기(Read)가 압도적으로 많은 데이터가 많을 때 
- 추가 인프라 비용 없이 캐시를 도입하고 싶을 때

레디스 캐시가 유리한 상황

- 여러 서버 인스턴스가 동일한 캐시 데이터를 공유해야 하는 경우 ( 분산 환경 )
- 로그인 세션, 인증 토큰 등 데이터 일관성이 매우 중요한 서비스인 경우
- 서버 재시작에도 캐시 데이터가 유지되어야 하는 경우 

카페인 캐시 사용법

1. 의존성 추가 ( build.gradle )

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

2. application.yml 설정

spring:
  cache:
    type: caffeine
  caffeine:
    spec: initialCapacity=10,maximumSize=1000,expireAfterWrite=60s

3. 자바 설정 (CacheConfig)

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;

@EnableCaching
@Configuration
public class CacheConfig {
    @Bean
    public Caffeine<Object, Object> caffeineConfig() {
        return Caffeine.newBuilder()
                .expireAfterWrite(60, TimeUnit.SECONDS)
                .initialCapacity(10)
                .maximumSize(1000);
    }

    @Bean
    public CacheManager cacheManager(Caffeine<Object, Object> caffeine) {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        cacheManager.setCaffeine(caffeine);
        return cacheManager;
    }
}

4. 캐시 적용 (@Cacheable)

@Service
public class ArticleService {
    @Cacheable(value = "popular-articles")
    public List<Article> getPopularArticles() {
        // 실제로는 DB에서 인기글 목록을 조회
        return articleRepository.findTop10ByOrderByViewCountDesc();
    }
}

-> 인기글 목록을 DB에서 꺼내오고, 이후 요청부터는 캐시에서 자동 반환 

5. 캐시 삭제 (@CacheEvict)

@CacheEvict(value = "popular-articles", allEntries = true)
public void updateArticle(ArticleDto dto) {
    // 게시글 수정 시 캐시 삭제
}

카페인 캐시의 장점

- DB 트래픽 감소효과 : 반복적인 조회 데이터를 캐싱처리하여 DB트래픽 감소 및 비용절감 효과 
- 응답속도 증가 : 고객 체감 속도 개선을 통한 앱 속도 개선 가능
- 서버 비용 절감 : 잘 만든 캐시로 DB/서버 인스턴스 수를 줄일 수 있으며, 클라우드 비용 최적화

실무 팁 (Tip)

- TTL 시간을 너무 길게 잡지 말 것. ( 데이터 불일치 이슈가 생길 수 있음 )
- 서버가 여러 대라면? 각 서버마다 캐시가 달라질 수 있으니, 데이터 일관성이 중요한 경우엔 레디스 사용 추천 ( 레디스가 싫다면 TTL을 짧게 잡아서 일관성 유지 )
- 캐시 용량 주의 : 너무 큰 데이터셋을 캐시에 올리게 되면 JVM 메모리 부족으로 장애가 일어날 수 있음

캐시는 단순히 응답 속도를 빠르게 만드는 도구는 아닙니다. DB 부하감소, 서버 비용절감, 트래픽 폭주 대응, 고객경험 개선, 그리고 서비스의 안정성까지 모두 챙길 수 있는 백엔드의 핵심 전략입니다. 특히 카페인 캐시처럼 쉽고 빠르게 구현할 수 있는 인메모리 캐시는 적은 투자로 큰 성능을 가져다주는 방식이기에 내 서비스에 특성과 구조를 잘 살펴서 알맞은 캐시 전략을 고민해 보세요.

Comments