이전 프로젝트에서 매번 조회를 할 때마다 DB를 거치기 때문에 조회 시간이 오래걸린다는 상황을 인지했다.
(물론 쿼리부터 성능이 아직 말이 아니다..)
그렇게 조회 시간 단축을 고민하며 알게 된 Redis를 이용한 반복 조회 시간 단축 방법이 있었다.
이번 기회에 Redis를 리프레시 토큰에 사용하는 것 외에 다르게 사용해 볼 수 있을 것 같았다.
이미 리프레시 토큰 관리에 Redis를 이용했기 때문에 기본적인 RedisConfig 설정은 해놨었다.
@Configuration
public class RedisConfig {
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(
RedisConnectionFactory redisConnectionFactory // Redis 서버연결
) {
return new RedisMessageListenerContainer() {{
setConnectionFactory(redisConnectionFactory);
}};
}
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
return redisTemplate;
}
}
Redis를 사용한 서비스 코드
@Transactional(readOnly = true)
public Page<TourSimpleResponse> getTours(Long memberId, String regionName, Pageable pageable) {
String topic = buildTopic(regionName, pageable);
// Redis에서 데이터 가져오기
Object cachedData = redisCache.get(topic, String.valueOf(memberId));
if (cachedData != null) {
TourSimpleResponsePage tourSimpleResponsePage =
objectMapper.convertValue(cachedData, TourSimpleResponsePage.class);
return new PageImpl<>(
tourSimpleResponsePage.tourSimpleResponseList(), pageable, tourSimpleResponsePage.totalElements());
}
// 캐시에 데이터가 없으면 DB에서 조회
Page<TourSimpleResponse> tourSimpleResponses = (regionName == null) ?
tourItemRepository.findPopularTourItems(memberId, pageable) :
tourItemRepository.findPopularTourItems(Region.fromName(regionName).getAreaCode(), memberId, pageable);
// 조회한 데이터를 Redis에 저장
TourSimpleResponsePage tourSimpleResponsePage =
new TourSimpleResponsePage(tourSimpleResponses.toList(), tourSimpleResponses.getTotalElements());
redisCache.save(topic, String.valueOf(memberId), tourSimpleResponsePage);
return tourSimpleResponses;
}
private String buildTopic(String regionName, Pageable pageable) {
String baseTopic = TOUR_ITEM + " - ";
if (regionName == null) {
return baseTopic + pageable.toString();
} else {
return baseTopic + regionName + " - " + pageable.toString();
}
}
매번 DB에서 가져오던 조회 방식에서 Redis를 이용하니 반복된 조회 시간은 훨씬 단축됐다.
기존 코드 - 평균 조회 시간 50.7ms
Redis를 이용한 코드 - 평균 조회 시간 24.5ms
약 48% 조회 시간 단축에 성공했다!
'대충 넘어가지 않는 습관을 위한 기록' 카테고리의 다른 글
JPA 기록 - 엔티티 매핑 : ddl-auto, 필드와 컬럼 매핑 (1) | 2024.04.05 |
---|---|
JPA 기록 - 영속성 관리 : 내부 동작 방식 (1) | 2024.04.02 |
동시성 처리 기록 (1) | 2024.02.25 |
엘라스틱 캐시를 이용한 redis 적용 (0) | 2024.01.24 |
스프링 시큐리티 (jwt) 관련 기능 고민 기록 (0) | 2023.12.30 |