排行榜功能是乙個很普遍的需求。使用 redis 中有序集合的特性來實現排行榜是又好又快的選擇。
一般排行榜都是有實效性的,比如「使用者積分榜」。如果沒有實效性一直按照總榜來排,可能榜首總是幾個老使用者,對於新使用者來說,那真是太令人沮喪了。
首先,來個「今日積分榜」吧,排序規則是今日使用者新增積分從多到少。
那麼使用者增加積分時,都操作一下記錄當天積分增加的有序集合。
假設今天是 2015 年 04 月 01 日,uid 為 1 的使用者因為某個操作,增加了 5 個積分。
redis 命令如下:
zincrby rank:20150401 5 1
假設還有其他幾個使用者也增加了積分:
zincrby rank:20150401 1 2
zincrby rank:20150401 10 3
看看現在有序集合 rank:20150401 中的資料(withscores 引數可以附帶獲取元素的 score):
zrange rank:20150401 0 -1 withscores
1) "2"
2) "1"
3) "1"
4) "5"
5) "3"
6) "10"
按照分數從高到低,獲取 top10:
zrevrange rank:20150401 0 9 withscores
1) "3"
2) "10"
3) "1"
4) "5"
5) "2"
6) "1"
因為只有三個元素,所以就查詢出了這些資料。
如果每天記錄當天的積分排行榜,那麼其他花樣百出的榜單也就簡單了。
比如「昨日積分榜」:
zrevrange rank:20150331 0 9 withscores
利用並集實現多天的積分總和,實現「上週積分榜」:
zunionstore rank:last_week 7 rank:20150323 rank:20150324 rank:20150325 rank:20150326 rank:20150327 rank:20150328 rank:20150329 weights 1 1 1 1 1 1 1
這樣就將 7 天的積分記錄合併到有序集合 rank:last_week 中了。權重因子 weights 如果不給,預設就是 1。為了不隱藏細節,特意寫出。
那麼查詢上週積分榜 top10 的資訊就是:
zrevrange rank:last_week 0 9 withscores
「月度榜」、「季度榜」、「年度榜」等等就以此類推。
下面給出乙個 php 版的簡單實現。使用 redis 依賴於 php 擴充套件 phpredis,**還依賴於 carbon 庫,用於處理時間。**量很少,所以就不敲注釋了。
namespace blog\redis;
use \redis;
use carbon\carbon;
class ranks , $dates);
$weights = array_fill(0, count($keys), 1);
$this->redis->zunion($outkey, $keys, $weights);
return $this->redis->zrevrange($outkey, $start, $stop, true);
public function getyesterdaytop10() {
$date = carbon::now()->subdays(1)->format('ymd');
return $this->getonedayrankings($date, 0, 9);
public static function getcurrentmonthdates() {
$dt = carbon::now();
$days = $dt->daysinmonth;
$dates = array();
for ($day = 1; $day <= $days; $day++) {
$dt->day = $day;
$dates = $dt->format('ymd');
return $dates;
public function getcurrentmonthtop10() {
$dates = self::getcurrentmonthdates();
return $this->getmultidaysrankings($dates, 'rank:current_month', 0, 9);
redis排重 使用Redis實現實時排名
redis用途很廣泛,分布式使用者session快取 爬蟲url佇列 活動頁面的動態列表資訊等。使用redis實現排行榜系統也是很常見的方案。假如設計乙個積分排名系統。如果積分資料都存放在資料庫中,積分的更新是動態的,每次訪問排行頁面都需要對資料進行重新排序,在真實的產品應用中幾乎是不可接受的。re...
redis排重 使用redis進行排行榜的小秘訣
前言 在日常一些簡單的活動開發中,我經常會碰到需要對使用者的分值等進行排行,此時一般會選擇redis的有序集合對使用者的分數進行儲存,但是不同的場景排行榜的方式也略有不同,以下根據自己日常的開發進行了一下歸納總結 redis 有序集合 sorted set 首先簡單介紹下什麼是有序集合。redis ...
redis排重 使用 Redis 實現排行榜功能
排行榜功能是乙個很普遍的需求。使用 redis 中有序集合的特性來實現排行榜是又好又快的選擇。一般排行榜都是有實效性的,比如 使用者積分榜 如果沒有實效性一直按照總榜來排,可能榜首總是幾個老使用者,對於新使用者來說,那真是太令人沮喪了。首先,來個 今日積分榜 吧,排序規則是今日使用者新增積分從多到少...