우당탕탕
Redis 캐싱 Spring Boot 연동 직접 구현해보니 쾌적한 성능 체감했어요 본문
사실 이걸 구현하다가 생각보다 삽질을 많이 했어요. Spring Boot 프로젝트에 Redis 캐시를 붙이면서 데이터베이스 쿼리 부담을 줄이고 응답 속도를 빠르게 만들려고 했거든요. 그런데 설정부터 테스트까지 하나하나 해보면서 직접 경험하지 않으면 이해하기 어려운 부분이 많더라고요.
이 글에서는 제가 Redis를 Spring Boot에 연동하고, 캐싱 전략을 세워봤던 과정을 자세히 담았어요. 실제 쿼리를 작성하고 최적화하면서 느꼈던 점도 함께 적었으니, Redis 캐시를 처음 도입하거나 최적화 고민 중이라면 분명 도움이 될 거예요.
Redis 캐싱 Spring Boot 연동 직접 구현해보니 관련 정보
개발 환경 / 버전 정보
이번 프로젝트는 Java 17과 Spring Boot 3.2을 사용했어요. Redis 서버는 로컬에 Redis 7.0을 올렸고, 의존성으로는 spring-boot-starter-data-redis를 넣었답니다.
Redis 캐시 이렇게 붙였습니다
사실 이 부분이 가장 중요한데, 저는 Spring Cache 추상화를 이용했어요. 직접 RedisTemplate 쓰는 것도 방법이지만, 캐싱 프로세스를 깔끔하게 하려면 Spring Cache가 훨씬 편하더라고요. 설정부터 간단히 해볼게요.
@Configuration
@EnableCaching
public class RedisConfig {
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory("localhost", 6379);
}
@Bean
public RedisCacheManager cacheManager(LettuceConnectionFactory connectionFactory) {
RedisCacheConfiguration cacheConfig = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(10)) // 캐시 유효기간 10분 설정
.disableCachingNullValues();
return RedisCacheManager.builder(connectionFactory)
.cacheDefaults(cacheConfig)
.build();
}
}
캐시 TTL(Time To Live)을 10분으로 잡아서 데이터가 너무 오래 남아있지 않도록 했어요. 보통 자주 바뀌는 데이터는 이 정도가 적당하더라고요. 다음은 서비스 코드에 @Cacheable 애노테이션을 붙인 예입니다.
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Cacheable(value = "userCache", key = "#userId")
public User getUserById(Long userId) {
System.out.println("DB 조회 발생: " + userId);
return userRepository.findById(userId).orElse(null);
}
}
캐시가 없을 때만 DB 쿼리가 발생하기 때문에 "DB 조회 발생:" 로그로 확인할 수 있어요. 실제로 Redis에 캐시가 쌓이면 DB 호출이 줄면서 체감 성능이 훨씬 좋아지더라고요.
Redis 캐싱 Spring Boot 연동 직접 구현해보니 관련 정보
여기서 삽질했던 부분들
진짜 한참 헤맸던 게 캐시 키 설정이었어요. 기본 키가 적절하지 않으면 서로 다른 데이터가 뒤섞여서 엉뚱한 값이 나왔거든요. 그래서 키를 명확하게 직접 지정해주는 게 중요하더라고요.
// 잘못된 사용 예
@Cacheable(value = "userCache") // key 지정 안 하면 기본 키가 메서드 파라미터 전체를 조합
public User getUserById(Long userId) { ... }
위처럼 키를 안 쓰면 파라미터가 객체일 때 의도치 않은 결과가 종종 나와서 꼭 키를 문자열로 지정하는 게 안전해요.
또 Redis 서버가 안 켜져 있을 때 서비스 자체가 예외를 뱉어서 당황했는데, 이 부분은 캐시 에러를 무시하도록 예외 처리를 넣어 해결했어요.
심화: 이렇게도 캐시 활용해보세요
저는 정적인 데이터뿐 아니라 자주 변경되는 리스트 조회 쪽에도 캐시를 걸어봤는데요, 이때는 캐시 무효화 전략도 중요해지더라고요. 예를 들어 데이터가 변경됐을 때 @CacheEvict 애노테이션으로 관련 캐시를 꼭 지우는 식입니다.
@CacheEvict(value = "userCache", key = "#user.id")
public void updateUser(User user) {
userRepository.save(user);
}
이렇게 안 하면 수정해도 캐시가 남아있어 이전 데이터가 계속 보여서 큰일 나더라고요.
자주 물어보시는 것들
Q. 캐시 TTL을 너무 길게 잡으면 문제 없나요?
A. 바뀌는 데이터를 오래 캐싱하면 당연히 최신성이 떨어져서 사용자 경험이 나빠져요. 그래서 TTL은 서비스 특성에 맞춰 조절하는데, 너무 길면 @CacheEvict 같은 무효화 전략을 꼭 같이 써야 해요.
Q. Redis 캐시 때문에 장애가 날 수도 있나요?
A. 네, Redis가 다운되면 캐시를 못 쓰니까 DB 부하가 급증할 수 있어요. 저는 Redis 연결 실패 시 서비스를 계속하도록 예외 처리를 넣어서 큰 장애는 막았답니다.
Redis 캐싱 Spring Boot 연동 직접 구현해보니 관련 정보
직접 Redis 캐싱을 Spring Boot에 붙여보면서 어떻게 설정하고, 어디서 주의해야 하는지 확실히 알게 됐어요. 특히 캐시 키 관리와 TTL 설정, 그리고 무효화가 핵심이라는 걸 다시 느꼈는데요. 이 경험이 쾌적한 애플리케이션 성능을 고민하는 분들께 조금이나마 도움이 되었으면 해요. 앞으로는 더 다양한 데이터 최적화도 시도해보려 합니다.
'Database' 카테고리의 다른 글
| MongoDB 처음 써보면서 RDBMS와 달라서 놀랐던 부분들 직접 정리했어요 (0) | 2026.05.30 |
|---|---|
| MongoDB 처음 써보면서 RDBMS와 확실히 달랐던 부분들 정리해봤어요 (0) | 2026.05.29 |
| MongoDB 처음 써보면서 RDBMS와 달라서 막혔던 부분들 정리 (0) | 2026.05.20 |
| MongoDB 처음 써보면서 RDBMS와 다른 점 직접 체험하며 정리해봤어요 (0) | 2026.05.19 |
| [MySQL] 트랜잭션 격리 수준(Isolation Level)에 대한 이해 (0) | 2024.09.22 |
