게임 랭킹을 구현해야 합니다. 점수가 바뀔 때마다 순위가 실시간으로 갱신되어야 하고, 특정 플레이어의 순위를 즉시 알 수 있어야 합니다. 데이터베이스에서 매번 정렬 쿼리를 날리면 느립니다. Redis Sorted Set은 이 문제를 O(log N)에 해결합니다.
# 원소 추가 (멤버, 점수)
ZADD ranking 9800 "player:A"
ZADD ranking 8500 "player:B"
ZADD ranking 7200 "player:C"
# 여러 개 한 번에
ZADD ranking 9800 "player:A" 8500 "player:B" 7200 "player:C"
# 점수 증가
ZINCRBY ranking 500 "player:C"
# player:C 점수 → 7700
# 오름차순으로 0~2위 (낮은 점수부터)
ZRANGE ranking 0 2
# 내림차순으로 0~2위 (높은 점수부터, 일반적인 랭킹)
ZREVRANGE ranking 0 2
# 점수도 함께 조회
ZREVRANGE ranking 0 2 WITHSCORES
# 1) "player:A"
# 2) "9800"
# 3) "player:B"
# 4) "8500"
# 5) "player:C"
# 6) "7700"
# 원소 개수
ZCARD ranking
ZRANGE/ZREVRANGE: 인덱스 범위로 원소를 조회. Z는 Sorted Set을 의미하며, REV가 붙으면 역순(내림차순)입니다.
# 오름차순 순위 (0부터 시작)
ZRANK ranking "player:C"
# 0 (가장 낮은 점수)
# 내림차순 순위 (일반적인 랭킹 표현)
ZREVRANK ranking "player:A"
# 0 (1등)
ZREVRANK ranking "player:B"
# 1 (2등)
# 점수 조회
ZSCORE ranking "player:A"
# "9800"
# 특정 원소 삭제
ZREM ranking "player:C"
# 점수 범위로 삭제
ZREMRANGEBYSCORE ranking 0 7000
# 순위 범위로 삭제
ZREMRANGEBYRANK ranking 0 2
# 점수 8000 이상인 플레이어
ZRANGEBYSCORE ranking 8000 +inf WITHSCORES
# 점수 7000~9000인 플레이어
ZRANGEBYSCORE ranking 7000 9000
# 상위 3명만
ZREVRANGEBYSCORE ranking +inf -inf WITHSCORES LIMIT 0 3
# 점수 갱신
ZINCRBY game:ranking 200 "user:1000"
# 상위 10명 조회
ZREVRANGE game:ranking 0 9 WITHSCORES
# 내 순위 (1등이 1위, +1 보정)
rank=$(ZREVRANK game:ranking "user:1000")
# rank + 1 = 나의 순위
# 글 조회 시 조회수 증가
ZINCRBY popular:posts 1 "post:1000"
# 오늘 인기 글 Top 10
ZREVRANGE popular:posts 0 9 WITHSCORES
# 매일 자정 초기화
DEL popular:posts
# 낮은 숫자 = 높은 우선순위
ZADD job:queue 1 "urgent:payment:500"
ZADD job:queue 5 "normal:report:123"
ZADD job:queue 10 "low:cleanup:789"
# 가장 높은 우선순위 작업 꺼내기
ZPOPMIN job:queue
# "urgent:payment:500"
ZPOPMIN/ZPOPMAX: 가장 낮은/높은 점수의 원소를 꺼내는 명령. Redis 5.0에서 추가되었습니다.
Unix 타임스탬프를 점수로 사용하면 시간 기반 정렬을 구현할 수 있습니다.
# 게시글 등록 (점수 = 등록 시각)
ZADD posts:timeline 1718700000 "post:1"
ZADD posts:timeline 1718786400 "post:2"
# 최근 글 순으로 조회
ZREVRANGE posts:timeline 0 9
# 특정 기간 글 조회 (2026-06-18 ~ 2026-06-19)
ZRANGEBYSCORE posts:timeline 1718668800 1718755200
# 요청 시각을 점수로 추가
ZADD rate:user:1000 1718700000123 "req:uuid1"
# 1분 이전 요청 제거
ZREMRANGEBYSCORE rate:user:1000 0 1718699940123
# 남은 요청 수로 제한 판단
ZCARD rate:user:1000
# 100 초과 시 거부
Sorted Set은 두 가지 자료구조를 결합해 구현합니다.
Skip List: 여러 레벨의 포인터를 이용해 정렬된 데이터에서 O(log N) 검색을 가능하게 하는 자료구조. B-Tree와 유사한 성능을 더 단순하게 구현합니다.