https://dean83.tistory.com/323 을 통해 Redis 를 이용한 캐시 사용법 정리 및 기본적인 내용을 정리해 두었다.
로컬 캐시는 개인적으로는 잘 안쓸거 같아서 정리를 하지 않았는데, 경우에 따라서는 사용하는곳이 꽤 있는거 같다.
로컬캐시는 여러개가 있는데 Caffein이 많이 쓰이기도 하고, 여러 기능이 다양해서 많이 쓰인다고 한다. (모체가 구글에서 제작)
build.gradle 설정 추가
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-cache'
implementation 'com.github.ben-manes.caffeine:caffeine'
}
application.yaml 설정 추가
spring:
cache:
type: caffeine
CacheManager 구성
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public CaffeineCacheManager cacheManager() {
CaffeineCacheManager cacheManager =
new CaffeineCacheManager(
"userById",
"bookById",
"popularBooks"
);
cacheManager.setCaffeine(
Caffeine.newBuilder()
.initialCapacity(1_000)
.maximumSize(10_000)
.expireAfterAccess(10, MINUTES)
.expireAfterWrite(30, TimeUnit.MINUTES)
.recordStats()
);
);
return cacheManager;
}
}
- userById .... 인자값 : 미리 생성할 캐시 목록으로, @Cacheable 에서 사용할 이름들 (중요 캐시들을 미리 선언)
- initialCapacity : 초기 캐시 엔트리 갯수
- 너무 크게주면 메모리 낭비가 되므로, maximumSize의 10 ~ 20% 사이가 좋다.
- maximumSize : 최대 저장 가능한 엔트리 갯수로, 이 숫자를 넘기면 자동으로 삭제한다
- expireAfterWrite : 캐시에 저장한 시간이 이 시간을 넘어가면 삭제
- expireAfterAccess : 마지막으로 접근한 시간이 이 시간을 넘어가면 삭제
- refreshAfterWrite : 정해진 시간마다 비동기로 캐시를 자동 갱신 하는 기능이나 잘 쓰지 않음.
- Redis를 사용하는쪽이 더 좋고, 비동기 제어 및 트랜잭션 관리가 어려움.
- recordStats() : 캐시 통계를 위해 반드시 호출해야 함
캐시 통계 내용 확인
구성하기 나름이나, 히트율이 낮을경우 알림 같은걸 추가 할 수도 있다.
예시로, 이대로 쓰면 로그가 엄청 많이 생성된다.
@Component
@RequiredArgsConstructor
@Slf4j
public class CacheMetricsScheduler {
private final CacheManager cacheManager;
/**
* 1분마다 모든 캐시 성능 출력
*/
@Scheduled(fixedRate = 60_000)
public void printAllCacheStats() {
log.info("========== Cache Metrics ==========");
for (String cacheName : cacheManager.getCacheNames()) {
Cache cache = cacheManager.getCache(cacheName);
if (cache == null) {
continue;
}
if (!(cache instanceof CaffeineCache)) {
continue;
}
CaffeineCache caffeineCache = (CaffeineCache) cache;
com.github.benmanes.caffeine.cache.Cache<Object, Object> nativeCache =
caffeineCache.getNativeCache();
CacheStats stats = nativeCache.stats();
log.info(
"[Cache: {}] size={}, hitRate={}, hitCount={}, missCount={}, evictionCount={}",
cacheName,
nativeCache.estimatedSize(),
String.format("%.2f", stats.hitRate()),
stats.hitCount(),
stats.missCount(),
stats.evictionCount()
);
if (stats.hitRate() < 0.6) {
log.warn("[Cache WARNING] {} hitRate={}", cacheName, stats.hitRate());
}
}
log.info("===================================");
}
}
'Backend > SpringBoot' 카테고리의 다른 글
| Prometheus + Grafana 를 이용한 모니터링 (0) | 2026.01.05 |
|---|---|
| Cache 를 Actuator에서 확인하기 (Caffein 예) (0) | 2026.01.05 |
| 서킷 브레이커 (0) | 2026.01.05 |
| MVC 환경에서 WebClient (0) | 2026.01.05 |
| Task Decorator (@Async 에서 MDC, SecurityContextHolder 정보 활용) (0) | 2026.01.02 |