개인의 기록
  • 소개
  • 프로젝트
  • 글
  • 링크

© 2026 newgirok

← 글 목록

Redis Sorted Set — 점수 기반 정렬 집합과 랭킹

2026년 1월 21일
RedisSorted Set랭킹리더보드우선순위 큐

게임 랭킹을 구현해야 합니다. 점수가 바뀔 때마다 순위가 실시간으로 갱신되어야 하고, 특정 플레이어의 순위를 즉시 알 수 있어야 합니다. 데이터베이스에서 매번 정렬 쿼리를 날리면 느립니다. 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

슬라이딩 윈도우 Rate Limiting

# 요청 시각을 점수로 추가
ZADD rate:user:1000 1718700000123 "req:uuid1"

# 1분 이전 요청 제거
ZREMRANGEBYSCORE rate:user:1000 0 1718699940123

# 남은 요청 수로 제한 판단
ZCARD rate:user:1000
# 100 초과 시 거부

내부 구현

Sorted Set은 두 가지 자료구조를 결합해 구현합니다.

  • Hash: 멤버 → 점수 조회를 O(1)으로 처리
  • Skip List: 점수 기반 범위 조회를 O(log N)으로 처리

Skip List: 여러 레벨의 포인터를 이용해 정렬된 데이터에서 O(log N) 검색을 가능하게 하는 자료구조. B-Tree와 유사한 성능을 더 단순하게 구현합니다.

← 이전 글Redis Set — 중복 없는 집합과 집합 연산
다음 글 →Redis 캐시 전략 — Cache Aside, Write Through, Write Back