OPEN HYPER STEP
← 목록으로 (Java+Spring)
JAVA · 76 / 99
java
CHAPTER 76 / 99
읽기 약 2
FUNCTION

캐싱: Redis + Spring Cache


핵심 개념

@Cacheable·@CacheEvict·@CachePut·Redis 연동·TTL — API 응답 캐싱.

본문

Spring Cache 어노테이션

JAVA📋 코드 (20줄)
@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofMinutes(10))
            .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(
                new StringRedisSerializer()))
            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(
                new GenericJackson2JsonRedisSerializer()));

        return RedisCacheManager.builder(factory)
            .cacheDefaults(config)
            .withCacheConfiguration("users",
                config.entryTtl(Duration.ofMinutes(30)))
            .build();
    }
}

@Cacheable / @CacheEvict / @CachePut

JAVA📋 코드 (32줄)
@Service
@RequiredArgsConstructor
public class UserService {
    private final UserRepository userRepo;

    // 첫 호출만 DB, 이후는 캐시
    @Cacheable(value = "users", key = "#id")
    public UserDto findById(Long id) {
        log.info("DB 조회: {}", id);  // 첫 호출만 로그
        User user = userRepo.findById(id)
            .orElseThrow(UserNotFoundException::new);
        return UserDto.from(user);
    }

    // 수정 시 캐시 무효화
    @CacheEvict(value = "users", key = "#id")
    public void delete(Long id) {
        userRepo.deleteById(id);
    }

    // 수정 + 캐시 갱신 (반환값 캐시)
    @CachePut(value = "users", key = "#result.id")
    public UserDto update(Long id, UpdateDto dto) {
        User user = userRepo.findById(id).orElseThrow();
        user.update(dto);
        return UserDto.from(user);
    }

    // 모든 user 캐시 삭제
    @CacheEvict(value = "users", allEntries = true)
    public void clearAll() {}
}

조건부 캐싱

JAVA📋 코드 (9줄)
// Premium 사용자만 캐싱
@Cacheable(value = "premium-data",
           key = "#userId",
           condition = "#user.isPremium()")
public DashboardData getDashboard(Long userId, User user) { /* ... */ }

// 결과가 null이면 캐시 안 함
@Cacheable(value = "users", unless = "#result == null")
public UserDto findById(Long id) { /* ... */ }

캐시 전략

📋 코드 (12줄)
Cache-Aside (Lazy Loading):
1. 캐시 조회 → 있으면 반환
2. 없으면 DB 조회 → 캐시 저장 → 반환
→ Spring Cache 기본 동작

Write-Through:
1. 쓰기 시 DB + 캐시 동시 갱신
→ @CachePut

Write-Behind:
1. 쓰기는 캐시만 — 비동기로 DB 반영
→ 직접 구현 필요 (RedisTemplate)

다음 챕터

CH.8 "비동기 처리: @Async + 이벤트" — 이메일 발송 비동기.


AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude

무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6

내 Spring 코드의 Redis 캐싱 부분을 분석해서
TTL·invalidation 전략와 개선 우선순위를 알려줘.
ChatGPT

무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro

Redis 캐싱 vs 다른 패턴 비교를
실전 사례 5개로 보여주고 Cache-Aside vs Write-Through를 알려줘.
Gemini

무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro

내 코드베이스 전체를 분석해서
Redis 캐싱 관련 캐시 누락·stale 위치를 보고해줘.
Grok

무료: Grok 4.1 / SuperGrok $30/mo

2026년 한국 기업의 Redis 캐싱 채택률과
한국 SaaS Redis 운영 패턴를 솔직히 알려줘.

⭐ 이것만 기억하세요
캐싱: Redis + Spring Cache 이 3가지만 확실히 잡으세요
1.@Cacheable + @CacheEvict + @CachePut 3종으로 대부분 캐싱 시나리오 해결
2.Redis TTL은 캐시별 다르게 — 자주 바뀌는 건 짧게, 거의 안 바뀌는 건 길게
3.다음 챕터 CH.8에서 비동기 처리 — @Async와 이벤트 패턴


공유하기
진행도 76 / 99