이번 주 과제는 기존에 구현된 선착순 쿠폰 발급과 인기상품 조회 기능을 Redis의 자료구조를 활용하여 리팩토링하는 것이었습니다. 단순히 캐시로만 알고 있던 Redis가 사실은 다양한 컬렉션 자료구조를 지원하고, 이를 통해 현업에서 랭킹 시스템, 이벤트 처리, 중복 제어 등 다양한 문제를 효율적으로 해결할 수 있다는 점을 새롭게 알게 되었습니다.
특히 Redis의 Sorted Set은 굉장히 강력한 기능이라고 느꼈습니다. 원래는 직접 구현해야 하는 실시간 랭킹 기능을 단 몇 개의 명령어로 처리할 수 있다는 점이 인상적이었습니다.

Redis 는 기본적으로 Key-Value 기반의 데이터 저장소입니다.
Value 로는 단순히 String 뿐 아니라 다양한 데이터 타입 ( Collections )를 지원하는데, 이를 활용해 현업에서 단순히 캐시 뿐 아니라 다양한 용도로 활용하고 있어요.
Strings
- 일반 문자열 ( 최대 512MB )
- 단순 증감 연산 혹은 문자열로 표현 가능한 모든 자료 저장하는 목적으로 활용
- 주요 명령어
- 수정 계열 : set, setnx, ..
- 조회 계열 : get, mget, ..
- INCR 계열 ( 단순 증감 )

Sets
- 저장된 원소의 Unique 함을 보장하는 자료구조
- Set 은 정렬을 보장하지 않음
- Set 자료구조를 위한 연산 지원 ( 교집합 / 합집합 / 차집합 등 )
- 주요 명령어
- 수정 계열 : sadd, smove
- 조회 계열 : smembers, scard, ..
- 제거 계열 : spop, srem
- 집합 계열 : sunion, sinter, sdif, ..

Sorted Sets
- set + score 가중치 필드가 추가된 자료구조
- 데이터 저장시, score 기반 오름차순 정렬로 저장됨
- score 값이 같은 경우, 사전순으로 정렬
- 주요 명령어
- 수정 계열 : ZADD
- 조회 계열 : ZRANGE, ZRANGEBYSCORE, ZRANK, ZSCORE, ..
- 제거 계열 : ZPOPMIN, ZPOPMAX, ZREM, ..
- 증감 계열 : ZINCRBY
- 집합 계열 : ZUNIONSTORE, ZINTERSTORE

Redis 기반의 랭킹 시스템
🎯 개요
- 실시간 랭킹이 필요한 시스템(게임 점수, 인기 콘텐츠, 상품 조회 등)에 적합
- Redis의 Sorted Set을 활용하여 효율적이고 빠른 랭킹 처리 가능
🧱 핵심 개념: Redis Sorted Set
- 구조: ZADD key score member
- 정렬: score 기준 오름차순 (낮은 점수 → 높은 점수)
- 특징:
- 같은 점수면 사전순 정렬
- 점수 기반으로 순위 계산이 가능함
- 조회 및 수정이 매우 빠름 (O(log N))
🔧 기본 명령어 예시
1. 점수 추가 및 갱신
ZADD game_ranking 1500 user123
ZADD game_ranking 3000 user456
ZADD game_ranking 2500 user789
2. 특정 사용자 점수 조회
ZSCORE game_ranking user123
3. 전체 랭킹 조회 (높은 점수가 1등)
ZREVRANGE game_ranking 0 9 WITHSCORES # Top 10
4. 특정 사용자 순위 조회
ZREVRANK game_ranking user123
5. 점수 증가 (예: 게임 승리 시 점수 부여)
ZINCRBY game_ranking 100 user123
📦 응용 예시: 일간 / 주간 랭킹 분리
키 구성 전략
- ranking:daily:20240429
- ranking:weekly:2024-W18
TTL 설정
- 일간 랭킹은 하루 후 자동 만료
- 주간 랭킹은 일주일 후 만료
EXPIRE ranking:daily:20240429 86400
⚠️ 주의할 점
- Sorted Set에 너무 많은 데이터를 넣으면 메모리 부담 ↑
- TTL 없이 데이터 계속 쌓이면 만료 누락 가능성 존재
- 동일 점수 처리 로직(예: 마지막 갱신 시간 기준 정렬 등) 필요 시 보완 로직 필요
🚀 실전 활용 예시
인기 상품 조회 랭킹 (24시간 클릭 수 기준)
- ZINCRBY product:ranking:clicks:20240429 1 product123
- 매일 자정 배치로 새로운 키 생성 및 TTL 부여
사용자 게임 랭킹
- ZADD game:ranking:user 5000 userA
- 클라이언트에게 ZREVRANK 결과 전달하여 등수 노출
📈 시각화 전략
- Redis에서 Top N을 가져와 DB 캐싱 → 사용자에게 제공
- 그래프 구성: 시간대별 랭킹 변동, 내 순위 추이 등 추가 분석 가능
✅ 요약
기능 Redis 명령어
| 점수 등록/수정 | ZADD, ZINCRBY |
| 순위 조회 | ZREVRANK, ZREVRANGE |
| 점수 조회 | ZSCORE |
| 데이터 만료 | EXPIRE |
📚 참고
- Redis 공식 문서: https://redis.io/commands/zadd/
- Redis TTL 관리: https://redis.io/docs/manual/key-expiration/
과제
Step14 by seuthootDev · Pull Request #14 · seuthootDev/hanghae-plus-backend
📌 PR 제목 규칙 [STEP14] 정승훈 - (e-commerce) 핵심 체크리스트 ✅ one: ranking design [✔] 적절한 설계를 기반으로 랭킹기능이 개발되었는가? [✔] 적절한 자료구조를 선택하였는가? 05c2b9c f625a44 8590803 67
github.com
과제는 다음과 같은 방식으로 구현했습니다:
- 선착순 쿠폰 발급 기능은 사용자 요청이 발생하면 Sorted Set으로 순위를 기록하고, 그 결과를 기반으로 실제 DB에 쿠폰을 발급하도록 했습니다.
- 단, 랭킹 기록 이후 DB 저장 직전에 장애가 발생할 수 있다는 리스크가 있어, 랭킹 기록과 로그 저장을 비동기적으로 처리하도록 설계했습니다. 이렇게 함으로써 장애 상황에서도 최소한 발급 순위 정보는 Redis에 안전하게 남길 수 있도록 했습니다.
- 또한, 인기 상품 조회 기능 역시 클릭 수를 Sorted Set에 누적하는 방식으로 구현해, 실시간으로 상품의 인기도를 반영할 수 있었습니다.
이번 과제를 통해 Redis가 단순 캐시 도구를 넘어 데이터를 구조적으로 다루고 실시간성을 보장하는 핵심 인프라가 될 수 있음을 체감했습니다. 앞으로도 이런 자료구조적 특성을 잘 이해하고 활용하면, 더 많은 비즈니스 로직을 단순화하면서도 성능을 확보할 수 있을 것 같습니다.
'항해+' 카테고리의 다른 글
| 항해+ 백엔드 코드 9주차 회고 : Kafka 메세지 큐 (0) | 2025.09.09 |
|---|---|
| 항해+ 백엔드 코드 8주차 회고 : Event 기반 Transaction (1) | 2025.08.31 |
| 항해+ 백엔드 코드 6주차 회고 : 분산락 + 캐시 (1) | 2025.08.18 |
| 항해+ 백엔드 코드 5주차 회고 : 동시성 처리(Concurrency Control) 과제 정리 – 데이터 정합성과 성능 동시 확보하기 (항해 부트캠프 할인코드 있음) (4) | 2025.08.09 |
| 항해+ 백엔드 코드 4주차 회고 (2) | 2025.08.02 |