Redis 를 활용하면 리더보드(순위표), 장바구니 등을 간단히 구현할 수 있다
여기서는 리더보드를 구현하는 테스트를 진행한다
- 요구사항 : 제일 많이 구매한 상품 10개 조회
ERD

- Product 와 Order 추가
Sorted Set 을 활용한 리더보드 구현
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, ProductDto> rankTemplate(
RedisConnectionFactory redisConnectionFactory
) {
RedisTemplate<String, ProductDto> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
template.setKeySerializer(RedisSerializer.string());
template.setValueSerializer(RedisSerializer.json());
return template;
}
}
- 사용할
RedisTemplate를 빈으로 정의 application.yml기준으로 설정된 커넥션을 연결
@Service
@RequiredArgsConstructor
public class ProductService {
private final ProductRepository productRepository;
private final OrderRepository orderRepository;
private final RedisTemplate<String, ProductDto> rankTemplate;
public void purchase(Long id) {
Product product = productRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
ZSetOperations<String, ProductDto> rankOps = rankTemplate.opsForZSet();
orderRepository.save(new Order(product));
rankOps.incrementScore("soldRanks", ProductDto.from(product), 1);
}
public List<ProductDto> getMostSold() {
Set<ProductDto> ranks = rankTemplate.opsForZSet().reverseRange("soldRanks", 0, 9);
if (ranks == null) {
return Collections.emptyList();
}
return ranks.stream().toList();
}
}
- 상품 구매와 많이 팔린 상품 조회 구현
- 상품 구매시 DB에 데이터를 저장하고 기존에 정의했던
RedisTemplate에서 ZSET 연산을 활용하여 스코어를 1로 정의ZADD를 하지 않은 이유는 순위표 특성상 INC 연산만 수행하면 되므로 굳이 필요없음- 더불어 초기 데이터가 없는 상황에서도 INC 연산을 수행하면 자동으로 데이터를 생성하고 작업을 수행한다
- 역순으로 0 ~ 9 까지 데이터 조회
이를 만약 DB 쿼리로 조회해야 한다면
SELECT p.name, SUM(o.count)
FROM products p
JOIN orders o
ON p.id = o.product_id
GROUP BY p.id
ORDER BY SUM(o.count) DESC
LIMIT 10
- 위와 같은 쿼리로 매번 요청마다 DB 접근을 수행해야함
- 더불어 요청마다 집계함수를 실행하므로 효율적이지 않음
테스트 코드
'학습일지 > Redis' 카테고리의 다른 글
| Redis Purge 를 사용할 경우 문제점 (1) | 2025.10.23 |
|---|