用 Redis 實作 Leaderboard(排行榜)

Redis 更新於 Oct 9, 2026

Sorted set (ZSET)

用 Redis 做排行榜是常見又有效率的做法,尤其在你需要快速讀寫與排名的時候。Redis 剛好內建一個非常適合的資料結構:Sorted Set(ZSET)。


🧠 Redis Sorted Set 入門

Redis 的 Sorted Set 是一組不重複的字串(例如 user ID 或帳號名稱),每一個都配上一個浮點數的分數(score)。整個集合會自動依分數排序。

對排行榜來說:

  • 玩家 / 使用者 ID 就是 member。
  • **分數(例如積分、擊殺數、評分)**就是 sorted set 裡的 score。

✅ Redis 排行榜的基本操作

1. 新增或更新玩家分數

bash
ZADD leaderboard <score> <user_id>

✅ 使用者不存在就新增,已經在集合裡就更新分數。

範例:

bash
ZADD leaderboard 1500 "user:123"
ZADD leaderboard 1800 "user:456"

2. 取前 N 名

bash
ZREVRANGE leaderboard 0 N-1 WITHSCORES
  • 用 ZREVRANGE 取由高到低(分數最高的在前)。
  • WITHSCORES 會連分數一起回傳。

範例:

bash
ZREVRANGE leaderboard 0 9 WITHSCORES  # Top 10 players

3. 取某位玩家的排名

bash
ZREVRANK leaderboard <user_id>
  • 回傳該玩家在遞減排序下的排名,從 0 開始。

範例:

bash
ZREVRANK leaderboard "user:123"  # e.g., returns 5

4. 取某位玩家的分數

bash
ZSCORE leaderboard <user_id>

範例:

bash
ZSCORE leaderboard "user:123"  # e.g., returns 1500.0

5. 移除玩家

bash
ZREM leaderboard <user_id>

範例:

bash
ZREM leaderboard "user:123"

🧱 可以再加的東西

🕐 依時間切分的排行榜

週榜、月榜的做法:

  • 每個時間區間用各自的 key:

    • leaderboard:weekly:2025-W20
    • leaderboard:monthly:2025-05
  • 用排程工作歸檔或刪掉舊的排行榜。

🧾 附帶資料(metadata)

Redis Sorted Set 沒辦法直接存額外資料(例如暱稱、頭像)。做法:

  • sorted set 裡只放 user ID。

  • 使用者的其他資料放在 Redis hash 或另一個資料庫:

    bash
    HGETALL user:123  # e.g., {"username": "Alice", "avatar": "..."}
    

🔁 分數累加

bash
ZINCRBY leaderboard 100 "user:123"

把 user:123 現有的分數加 100。


🧪 範例情境(遊戲)

bash
ZADD game:leaderboard 2000 "player:alice"
ZADD game:leaderboard 1900 "player:bob"
ZREVRANGE game:leaderboard 0 4 WITHSCORES  # top 5
ZREVRANK game:leaderboard "player:alice"   # alice's rank

🧩 可擴展性的幾點注意

  • Redis 是記憶體內的:非常快,但沒開持久化(RDB/AOF)資料就是易失的。
  • 使用者量非常大時,考慮把排行榜分片(sharding),或改用 Redis Cluster。
  • 如果精確度不是那麼關鍵,可以批次更新,或做近似排行榜(例如定期同步回資料庫)。