轉載自 https://duyanghao.github.io/redis-rank/
在業務開發過程中會遇到很多排行榜類似的需求,比如粉絲排行榜,播放排行榜等,排行榜本身含義非常清晰,就是維護一個列表,其中每個條目有一個score,依據score進行排序,形成排行榜。
redis zsetredis zset由於如下特性天生支持排行榜需求:
利用 redis zset 實現排行榜功能
現在假定有如下排行榜需求:實現一個粉絲Top10排行榜。簡單分析該需求,我們可以將用戶id作為member,用戶粉絲量作為score,
並設置 redis key 為 fans_rank 形成 redis zset
按照如下步驟你可以很容易地實現該功能:
1.zset添加member
如果用戶粉絲數目發生變動,則需要將該用戶重新添加到zset中進行排序,假定用戶id為user_id,粉絲量為score,則命令如下:
ZADD fans_rank user_id score
注意算法複雜度:
Time complexity: O(log(N)) for each item added, where N is the number of elements in the sorted set.
2.zset維持TopN操作
由於要維持TopN排行榜,所以最好的處理方法是每次ZADD後執行ZREMRANGEBYRANK,假定要維護TopN榜單,則命令如下:
ZREMRANGEBYRANK fans_rank 0 -(TopN+1)
注意:
這裡範圍是0——-(TopN+1),因為redis zset是按照從小到大方式排序的,所以需要維持的榜單是倒數TopN,也即從最後一個元素開始,倒數推TopN個
時間複雜度:
Time complexity: O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements removed by the operation.
3. zset刪除member
如果某個用戶進行註銷操作,或者被封號了,這個時候該用戶應該從redis zset中被踢掉,如下:
ZREM fans_rank user_id
注意算法複雜度:
Time complexity: O(M*log(N)) with N being the number of elements in the sorted set and M the number of elements to be removed.
4、zset範圍讀取
最後是獲取排行榜TopN數據,命令如下:
ZREVRANGE fans_rank 0 (TopN-1) withscores
注意:
這裡範圍是0——TopN-1,原因是:redis zset下標從0開始,而ZREVRANGE是倒序取數據
redis zset ZRANGE與ZREVRANGE當元素score相同時會默認根據member字典序排序
withscores會將member與對應score一起返回
算法複雜度:
Time complexity: O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements returned.
通過如上四個步驟就可以順利完成排行榜核心邏輯開發
這裡給出redis zset與排行榜功能相關的其它幾個常用命令:
順序取數據——ZRANGE
計算長度——ZCARD