优化redis中的大值,以便使用排序集进行排序

ep6jt1vc  于 2021-06-10  发布在  Redis
关注(0)|答案(1)|浏览(368)

我们使用redis对500万用户的手机游戏进行排名,我们使用排序集进行排名,有些排名值比较大,超过几百mb,我们的集群分布不均衡,有没有好的方法来优化这个。现在,我们正在考虑将键拆分为分数的不同子范围(1~100101~200201~300,等等),但是这增加了很多复杂性,因为我们有不同的排名,每个都有不同的分数范围。而且,维护和配置起来也相当困难。你能帮我提供一些指导吗,提前谢谢。

bybem2ql

bybem2ql1#

努力优化价值结构。看有没有空间压缩这个值。你的分类集以前是
“我的\u集”:
{“userid”:“1”,“profileid”:“123”,“name”:“john”}--111.0(分数),
{“userid”:“2”,“profileid”:“1234”,“name”:“peter”}--122.0(分数)
将其更改为{“u”:“1”,“p”:“123”,“name”:“john”}--111.0(分数)
每个人都可以用这么多的数据来保存
分开你的房间。您可以按排名范围拆分,而不是按分数范围拆分。假设排名对大多数人来说不需要精确。例如,我可能会关心我在游戏中排名是第二还是第三。但我不会在意/注意到我是否已经在中档了,我的排名从145645降到了14569(你最好显示145600,这样看起来就一样了)。
考虑到这一点,假设你预计有1000万玩家。你需要100个redis zsets,每个zsets可以容纳10万玩家。这些zset应该在集群中分布。
zset_001:排名前10万的选手所在地。
zset_002:排名在10万到20万之间的玩家所在地。
等等
你将有一个散列,保存每个玩家所属的zset号码。例如,player a,id:1234,您将保存player\u zset\u hash:{“1234”,“2”},以标记此player属于zset\u 002
为了检查玩家a的排名,你只需将玩家a在zset2中的排名加上10万。所以他可能会在比赛中排名10k+50=100050。第101名在zsetu 4的玩家c。所以他的总排名是4100k+101=4000101。
现在假设玩家a的分数有了很大的提高,你可以提高他的分数并检查他在zset002中的位置。说他现在在zset002排名第一
将他的得分与最后一个排名成员(比如玩家b)在zsetïu001中的得分进行比较,如果a的得分高于b,则交换他们的位置。将a放入zset\u 001,将b放入zset\u 002。相应地维护player\u zset\u hash。
当你添加新玩家时(假设每个玩家的起始分数为零,并且人们只能获得非负分数,并且你不会将玩家移出排名),你会将他们放到zset的最后一个,比如zset\u100。每天晚上,你都要检查最后一个zset的大小,如果它大于100k,就修剪它,然后把多余的zset移到一个新zset上(当然,记录下你在某处的所有zsets名称)
需要注意的一点是:您可能经常检查zset\u001,因此您的redis集群读取负载现在变得不均匀。您可以考虑让每台服务器每五秒钟检查一次排名,并将其缓存在本地服务器中,然后提供给访问者。而不是每次访问者需要检查排名时就点击redis。

***您也可以省略此步骤。并且每晚维护所有zset一次,因为zrank是o(logn)操作,而不是o(n)。毕竟,你可以容忍某个玩家的排名有一天不准确。假设他是200005名,现在他应该是199987名,而你却把他标为200001名。如果有某些游戏操作玩家得分显著,那么将此步骤合并到您的代码中。比如说,如果玩一个击中杰克壶,比较他的得分排名与其他zset后,他的得分变化。

相关问题