Redis中Sort Set如何使用?

2021-08-05 20:35:23 字數 3595 閱讀 7526

本文和大家分享的主要是

redis

中sort set

學習redis

有所幫助。

遊戲伺服器需要做乙個排行榜實時更新,如果沿用傳統的方法,一般是通過後端的定時任務去跑資料來生成排行榜資料,這種方法一方面無法滿足產品對功能實時性的要求,另一方面也一定程度上消耗伺服器端有限的資源。如果從每次資料庫讀取資料並進行排名(使用mysql的sort關鍵字進行排序),在關卡資料量的級數大時是一種效率低的方法。在查閱大量資料後,發現了redis中的有序集合(sort set)。

redis有序集合

redis 有序集合和集合一樣也是string型別元素的集合,且不允許重複的成員。不同的是每個元素都會關聯乙個double型別的分數。redis正是通過分數來為集合中的成員進行從小到大的排序。有序集合的成員是唯一的,但分數(score)卻可以重複。集合是通過雜湊表實現的,所以新增,刪除,查詢的複雜度都是o(1)。 集合中最大的成員數為 2^32 - 1。

應用場景

redis有序集合非常適用於有序不重複資料的儲存,例如遊戲開發中無處不在的排行榜,如等級排行榜,經驗排行榜,積分排行榜,歷史籌碼排行榜等。

相關命令

.zadd key score1 member1 [score2 member2] 向有序集合新增乙個或多個成員,或者更新已存在成員的分數

.zcard key 獲取有序集合的成員數

.zrange key start stop [withscores] 通過索引區間返回有序集合成指定區間內的成員

.zrank key member 返回有序集合中指定成員的索引

.zrem key member [member ...] 移除有序集合中的乙個或多個成員

.zrevrank key member 返回有序集合中指定成員的排名,有序集成員按分數值遞減(從大到小)排序

使用場景

1.輸入5個使用者的積分(uid, score), 實現top-3的查詢, 某個使用者更新積分, 再次查詢top-3.

2.新增積分:新增 (player0001, 1800), (player0002, 1987), (player0003, 965), (player0004, 4382), (player0005, 0), 並假定 

rank為sorted set的name. 3

.查詢5人的積分排行榜;

4.更新player005的積分;

5.重新查詢5人的積分排行榜;

php實現

排行榜思想:玩家每次積分發生變動時,更改redis中相應玩家的積分。當客戶端向伺服器請求呼叫getrank時,php伺服器呼叫zrangerank函式,返回相應的資料。

/**

* 更新排行榜資料*/

protectedfunctioninitrankinglist()

} /**

* 更新某個玩家的排行榜資料

*@param$playerid */

protectedfunctionsetplayerrank($playerid)

protectedfunctionsetstars($playerid)

/**

* 設定分數

*@param$star

*@param$rainbow

*@param$wing

*@param$playerid *

*@throws\\exception */

protectedfunctionzsetrank($star, $rainbow, $wing, $playerid)

$score = c("star_score") * $star + c("rainbow_score") * $rainbow + c("wing_score") * $wing;

$this->redis->zadd($this->rank, $score, $playerid); }

/*** 獲取某個使用者的排名

*@param$playerid *

*@returnint

*@throws\\exception */

protectedfunctionzrevrank($playerid)

$res =$this->redis->zrevrank($this->rank, $playerid);

return$res; }

/*** 獲取某個範圍的使用者排名

*@param$start

*@param$stop *

*@returnarray

*@throws\\exception */

protectedfunctionzrangerank($start, $stop)

$res =$this->redis->zrevrange($this->rank, $start, $stop, "withscores");

return$res; }

/*** 刪除某個使用者的排名

*@param$playerid *

*@returnint

*@throws\\exception */

protectedfunctionzdeleterank($playerid)

$res =$this->redis->zrem($this->rank, $playerid);

return$res; }

C 中如何使用redis

redis官網提供了很多開源的c 客戶端。例如,nhiredis servicestack.redis stackexchange.redis等。其中servicestack.redis應該算是比較流行的。它提供了一整套從redis資料結構都強型別物件轉換的機制並將物件json序列化。所以這裡只介紹...

redis 中如何切換db

一台伺服器上都快開啟200個redis例項了,看著就崩潰了。這麼做無非就是想讓不同型別的資料屬於不同的應用程式而彼此分開。那麼,redis有沒有什麼方法使不同的應用程式資料彼此分開同時又儲存在相同的例項上呢?就相當於mysql 資料庫,不同的應用程式資料儲存在不同的資料庫下。redis下,資料庫是由...

redis 中如何切換db

一台伺服器上都快開啟200個redis例項了,看著就崩潰了。這麼做無非就是想讓不同型別的資料屬於不同的應用程式而彼此分開。那麼,redis有沒有什麼方法使不同的應用程式資料彼此分開同時又儲存在相同的例項上呢?就相當於mysql 資料庫,不同的應用程式資料儲存在不同的資料庫下。redis下,資料庫是由...