DevOps/Redis
[Redis] @Cacheable을 이용한 Cache Aside 전략
ryuneng
2025. 1. 25. 00:04
반응형
Cache Aside 전략이란?
🔗 https://velog.io/@ryuneng2/Redis-캐시Cache-캐싱Caching이란
❓ @Cacheable
@Cacheable
어노테이션을 부착하면 Cache Aside 전략으로 캐싱이 적용된다.
즉, 해당 메서드로 요청이 들어오면 레디스를 먼저 확인한 후에 데이터가 있다면(Cache Hit
) 레디스의 데이터를 조회해서 바로 응답한다.
만약 데이터가 없다면(Cache Miss
) 메서드 내부의 로직을 실행시킨 뒤에 return 값으로 응답한 후, 그 return 값을 레디스에 저장한다.
✅ @Cacheable의 속성 값
- cacheNames : 캐시 이름 설정
- key : Redis에 저장할 Key의 이름 설정
- cacheManager : 사용할
cacheManager
의 Bean 이름을 지정
(RedisCacheConfig에 CacheManager 타입으로 정의한 메서드명과 일치해야 함)
💡 사용 예시
1. build.gradle 의존성 추가
dependencies {
// redis 추가
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
}
2. application.yml 설정
spring:
data:
redis:
host: ${REDIS_HOST}
port: ${REDIS_PORT}
logging:
level:
org.springframework.cache: trace # redis와 관련된 정보가 로그에 출력되도록 설정
3. RedisConfig 작성
@Configuration
public class RedisConfig {
@Value("${spring.data.redis.host}")
private String host;
@Value("${spring.data.redis.port}")
private int port;
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
// Lettuce라는 라이브러리를 활용해 Redis 연결을 관리하는 객체를 생성하고
// Redis 서버에 대한 정보(host, port)를 설정한다.
return new LettuceConnectionFactory(new RedisStandaloneConfiguration(host, port));
}
}
4. RedisCacheConfig 작성
@Configuration
@EnableCaching // SpringBoot의 캐싱 설정을 활성화
public class RedisCacheConfig {
@Bean
public CacheManager boardCacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration
.defaultCacheConfig()
// Redis에 Key를 저장할 때 String으로 직렬화(변환)해서 저장
.serializeKeysWith(
RedisSerializationContext.SerializationPair.fromSerializer(
new StringRedisSerializer()))
// Redis에 Value를 저장할 때 Json으로 직렬화(변환)해서 저장
.serializeValuesWith(
RedisSerializationContext.SerializationPair.fromSerializer(
new GenericJackson2JsonRedisSerializer()
)
)
// 데이터의 만료기간(TTL) 설정
.entryTtl(Duration.ofMinutes(1L)); // 1분마다 데이터 갱신
return RedisCacheManager
.RedisCacheManagerBuilder
.fromConnectionFactory(redisConnectionFactory)
.cacheDefaults(redisCacheConfiguration)
.build();
}
}
5. Service 클래스
@Service
public class BoardService {
private final BoardRepository boardRepository;
public BoardService(BoardRepository boardRepository) {
this.boardRepository = boardRepository;
}
@Cacheable(cacheNames = "getBoards", key = "'boards:page:' + #page + ':size:' + #size", cacheManager = "boardCacheManager")
public List<Board> getBoards(int page, int size) {
Pageable pageable = PageRequest.of(page - 1, size);
Page<Board> pageOfBoards = boardRepository.findAllByOrderByCreatedAtDesc(pageable);
return pageOfBoards.getContent();
}
}
6. Controller 클래스
@RestController
@RequestMapping("boards")
public class BoardController {
private final BoardService boardService;
public BoardController(BoardService boardService) {
this.boardService = boardService;
}
@GetMapping()
public List<Board> getBoards(@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size
) {
return boardService.getBoards(page, size);
}
}
이외에도 기본적으로 Board 엔티티 클래스, BoardRepository 클래스는 필요하다.
📌 요청 결과 확인
API를 요청하면 로그에서 Cache Aside 전략으로 캐싱이 적용되는 과정을 확인할 수 있다.
1. API 요청

2. 로그 확인
- 1) Cache Miss 상태
No cache entry for key 'boards:page:1:size:10' in cache(s) [getBoards]
- 2) 원래 로직에서 데이터베이스 조회하는 SQL문이 실행된다.
select b1_0.id,b1_0.content,b1_0.created_at,b1_0.title from boards b1_0 order by b1_0.created_at desc limit ?
select count(b1_0.id) from boards b1_0
- 3) 데이터베이스에서 클라이언트가 응답받은 데이터를 캐시(Redis)에 저장한다.
Creating cache entry for key 'boards:page:1:size:10' in cache(s) [getBoards]

3. 만료시간 이내에 API 재요청 (브라우저 새로고침)
4. 로그 확인
Cache entry for key 'boards:page:1:size:10' found in cache(s) [getBoards]
: 캐시에 저장된 데이터를 조회해서 반환했다는 의미이다.
📌 저장된 데이터 확인
- 1) cmd 실행 및
redis-cli
명령어 입력
혹은 Redis를 설치한 경로를 열어 redis-cli.exe를 실행 - 2)
keys *
명령어 입력 - Key가 잘 저장되었는지 확인 - 3)
get [key]
명령어 입력 - 해당 Key에 저장된 데이터 조회 - 4)
ttl [key]
명령어 입력 - 해당 Key의 만료시간 확인
Reference
< 해당 글은 velog에서 이전하며 옮겨온 글로, 가독성이 좋지 않을 수 있는 점 양해 부탁드립니다. >
🔗 velog 버전 보기 : https://velog.io/@ryuneng2/Redis-Cacheable을-이용한-Cache-Aside-전략