日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

基于TairZset輕松實現多維排行榜

TairZset是阿里云自研的數據結構,可實現256維度的double類型的分值排序。

原生Zset痛點

原生Redis支持的排序結構Sorted Set(也稱Zset)只支持1個double類型的分值排序,實現多維度排序時較為困難。例如通過IEEE 754結合拼接的方式實現多維度排序,此類方式存在實現復雜、精度下降、ZINCRBY命令無法使用等局限性。

TairZset介紹

借助阿里云自研的TairZset數據結構,可幫助您輕松實現多維度排序能力,相較于傳統方案具有如下優勢:

  • 最大支持256維的double類型的分值排序(排序優先級為從左往右)。

    對于多維score而言,左邊的score優先級大于右邊的score,以一個三維score為例:score1#score2#score3,TairZset在比較時,會先比較score1,只有score1相等時才會比較score2,否則就以score1的比較結果作為整個score的比較結果。同樣,只有當score2相等時才會比較score3。若所有維度分數都相同,則會按照元素順序(ascii順序)進行排序。

    為了方便理解,可以把#想象成小數點(.),例如0#99、99#90和99#99大小關系可以理解為0.99 < 99.90 < 99.99,即0#99 < 99#90 < 99#99。

  • 支持EXZINCRBY命令,不再需要取回當前數據,在本地增加值后再拼接寫回Tair

  • 支持和原生Zset相似的API。

  • 提供 普通排行榜分布式架構排行榜 的能力。

  • 提供開源TairJedis客戶端,無需任何編解碼封裝,您也可以參考開源自行實現封裝其他語言版本。

說明

關于本文中使用的TairZset相關命令,詳細解釋,請參見exZset

應用場景

排序需求常見于各類游戲、應用、獎牌等排行榜中,通常業務對排序的需求如下:

  • 支持增刪改查和反向排序,可根據分數范圍獲取相應用戶。

  • 快速返回排序請求的結果。

  • 具備擴展能力(即 分布式架構排行榜 ),在數據分片容量或計算能力不足時,可以將其擴展到其他數據分片。

實現獎牌榜

排名

參與方

金牌金牌

銀牌銀牌

銅牌銅牌

1

A

32

21

16

2

B

25

29

21

3

C

20

7

12

4

D

14

4

16

5

E

13

21

18

6

F

13

17

14

在獎牌榜中,從金、銀、銅牌的維度對參與方進行排名,先按照金牌數量排序;如果金牌數量一致,再以銀牌數量排序;如果銀牌數量也一致,再按照銅牌數量排序。在上述數據中,參與方E和F的金牌數相等,但是銀牌數參與方E大于F,因此參與方E排名靠前,通過TairZset的多維排序能力,您只需要使用簡單的API即可完成該需求。

客戶端設置依賴如下,采用阿里云的TairJedis-SDK

<dependency>
    <groupId>com.aliyun.tair</groupId>
    <artifactId>alibabacloud-tairjedis-sdk</artifactId>
    <version>1.6.0</version>
</dependency>

示例代碼如下:

JedisPool jedisPool = new JedisPool();
// 創建排行榜
LeaderBoard lb = new LeaderBoard("leaderboard", jedisPool, 10, true, false);

// 如果金牌數相同,按照銀牌數排序,否則繼續按照銅牌
//                    金牌 銀牌 銅牌
lb.addMember("A",     32,  21, 16);
lb.addMember("D",     14,  4,  16);
lb.addMember("C",     20,  7,  12);
lb.addMember("B",     25,  29, 21);
lb.addMember("E",     13,  21, 18);
lb.addMember("F",     13,  17,  14);

// 獲取 A 的排名
lb.rankFor("A"); // 1

// 獲取top3
lb.top(3);
// [{"member":"A","score":"32#21#16","rank":1}, 
// {"member":"B","score":"25#29#21","rank":2}, 
// {"member":"C","score":"20#7#12","rank":3}]

// 獲取整個排行榜
lb.allLeaders();
// [{"member":"A","score":"32#21#16","rank":1}, 
// {"member":"B","score":"25#29#21","rank":2}, 
// {"member":"C","score":"20#7#12","rank":3}, 
// {"member":"D","score":"14#4#16","rank":4}, 
// {"member":"E","score":"13#21#18","rank":5}, 
// {"member":"F","score":"13#17#14","rank":6}]

實現實時、小時、日、周和月維度的排行榜

該場景下的需求是實現月榜,那么這個Key就從月的維度進行索引。

利用TairZset的多級索引能力可以輕松實現不同時間范圍的排行榜。本案例中,月度的所有數據存儲在1個Key中(名稱為julyZset),寫入演示數據如下:

EXZINCRBY julyZset 7#2#6#16#22#100 7#2#6#16#22_user1
EXZINCRBY julyZset 7#2#6#16#22#50 7#2#6#16#22_user2
EXZINCRBY julyZset 7#2#6#16#23#70 7#2#6#16#23_user1
EXZINCRBY julyZset 7#2#6#16#23#80 7#2#6#16#23_user1
說明
  • 7#2#6#16#22#100表示7月第2周6號16點22分,更新其分數為100。

  • 7#2#6#16#22_user1表示此時間點更新的用戶,用戶名加入了具體時間前綴。

排行榜類型

具體實現的命令和返回結果

小時級別實時排行榜,即從當前時間往前推算一個小時(例如16:23~15:23)。

說明

如果訪問非常頻繁,可以將結果進行緩存。

查詢命令:

EXZREVRANGEBYSCORE julyZset 7#2#6#16#23#0 7#2#6#15#23#0

返回結果:

1) "7#2#6#16#22_user1"
2) "7#2#6#16#22_user2"

固定1小時排行榜,例如查詢16:00~17:00時間段的排行榜。

查詢命令:

EXZREVRANGEBYSCORE julyZset 7#2#6#17#0#0 7#2#6#16#0#0

返回結果:

1) "7#2#6#16#22_user1"
2) "7#2#6#16#22_user2"

日排行榜,例如查詢7月5號的日排行榜。

在查詢前,插入一條7月5號的數據:

EXZINCRBY julyZset 7#2#5#10#23#70 7#2#5#10#23_user1

返回結果:

"7#2#5#10#23#70"

查詢命令:

EXZREVRANGEBYSCORE julyZset 7#2#6#0#0#0 7#2#5#0#0#0

返回結果:

1) "7#2#5#10#23_user1"

周排行榜,例如查詢7月第2周的排行榜。

查詢命令:

EXZREVRANGEBYSCORE julyZset 7#3#0#0#0#0 7#2#0#0#0#0

返回結果:

1) "7#2#6#16#22_user1"
2) "7#2#6#16#22_user2"
3) "7#2#5#10#23_user1"

月排行榜,例如查詢7月的月排行榜。

在查詢前,插入一條7月20號的數據:

EXZINCRBY julyZset 7#4#20#12#20#50 7#4#20#12#20_user1

返回結果:

"7#4#20#12#20#50"

查詢命令:

EXZREVRANGEBYSCORE julyZset 7#6#0#0#0#0 7#0#0#0#0#0

返回結果

1) "7#4#20#12#20_user1"
2) "7#2#6#16#22_user1"
3) "7#2#6#16#22_user2"
4) "7#2#5#10#23_user1"