排行榜功能是乙個很普遍的需求。
設想在乙個遊戲中,有上百萬的玩家資料,如果現在需要你根據玩家的經驗值整理乙個前20名的排行榜,你會怎麼做呢?
你不可能 order by + limit 去實現
select * from game_socre order by score desc limit 0,20
使用 redis 中有序集合的特性來實現排行榜是又好又快的選擇。
首先介紹下,會用到的幾個命令及其它們的作用:
詳情看官網(redis中文)
zrange 檢視排行榜 (公升序)
zrevrange 檢視排行榜 (降序)
zadd 新增乙個資料
zrem 刪除乙個資料
zrank 獲取排名(公升序)
zrevrank 獲取排名 (降序)
了解命令之後,我們就可以試著玩一下了
127.0.0.1:6379> zrange rank_name 0 -1 withscores
(empty list or set)
查一下rank_name的排名表是空的,因為我們還沒對rank_name這個有序集合進行新增,0,-1表示查詢所有,withscores 表示帶數值。
我們使用zadd新增一些資料
127.0.0.1:6379> zadd rank_name 10 zhangsan
(integer) 1
127.0.0.1:6379> zadd rank_name 5 lisi
(integer) 1
127.0.0.1:6379> zadd rank_name 100 wangwu
(integer) 1
再次檢視
127.0.0.1:6379> zrange rank_name 0 -1 withscores
1) "lisi"
2) "5"
3) "zhangsan"
4) "10"
5) "wangwu"
6) "100"
127.0.0.1:6379> zrevrange rank_name 0 -1 withscores
1) "wangwu"
2) "100"
3) "zhangsan"
4) "10"
5) "lisi"
6) "5"
現在我想單獨檢視,zhangsan和lisi的排名
127.0.0.1:6379> zrank rank_name zhangsan
(integer) 1
127.0.0.1:6379> zrank rank_name lisi
(integer) 0
這裡要注意,redis的排名是從0開始的,所以一般會加1,比較沒有人說第0名。
更新的操作也是比較簡單的,可以使用zadd直接進行覆蓋。高併發情況下不推薦使用。例如投票這樣的排名表,一般使用原子自增操作,確保資料準確性
127.0.0.1:6379> zincrby rank_name 1 wangwu
"101"
127.0.0.1:6379> zrevrange rank_name 0 -1 withscores
1) "wangwu"
2) "101"
3) "zhangsan"
4) "10"
5) "lisi"
6) "5"
日排行榜,周排行榜,月排行榜基本你可以設定key+時間,如rank_name_20181230。
總結:redis的有序集合是乙個非常高效的資料結構,可以替代資料庫裡一些很難實現的操作。它的乙個典型應用場景就是排行榜,通過zrank可以快速得到使用者的排名,通過zrange可以快速得到top n的使用者列表,它們的複雜度都是o(log(n)),用來替代資料庫查詢可以大大提公升效能。
文章參考:
Redis 實現排行榜
不再介紹資料庫做實時排行榜的弊端,直接介紹redis的有序集合的強大作用。有序集合的資料和集合一樣,不能重複,但每個元素又可以關聯乙個分數,這個分數可以重複。需要注意的是,redis版本和命令變化較大,注意執行環境。執行環境 redis 庫版本 3.3.11 redis版本 3.2.1 生成資料 i...
熱門排行榜 redis實現
最近專案架構公升級,主要對效能方面進行公升級。之前熱門排行榜是通過對點讚量,閱讀量,收藏量等一系列的資料在db通過計算查出來的,效率方面不太好。因此考慮對該功能進行公升級優化,並且新增週期性排行榜如月排行,總排行。在引入快取之後首先考慮的是通過快取實現熱門排行榜的功能,但是考慮到首次引入快取擔心快取...
Redis排行榜的實現
遊戲闖關排行榜以通關次數正序 復活次數倒序和第一次通關的時間倒序來進行排序 第一步是組合排序分值,只有根據排序規則組合出來的分值,才能通過排序獲取到正確的排名。在排序規則中一般會有兩種方式,屬性正序和倒序。正序對於組合數字來說沒有影響,但是倒序就需要進行特殊的處理。那麼多說無益,上 排行榜顧名思義就...