redis 实时并列排行榜解决方案

AndersZhuo 发布于 2014/12/08 10:32
阅读 4K+
收藏 1
游戏项目中使用redis的Sorted-Sets 做排行榜,对于并列排行处理的机制为:

因为redis存储的是double类型,为64位

所以对于分数相同的情况,采用按照时间来排序。

为此,现在的设计为: double  64位  , 拆分为:  高32位 , 低32位

其中高32位存储真正的分数,低32位存储当时与某一个时刻的时间差(秒),这样就很好解决了并列排名,

不过支持的最大分为32位,即一个int

问题:
因为redis内部使用double类型,关于double的本身就有精度问题,

在<<计算机操作系统>>中,double 64位, 其中63位是符号位,62-52位位阶码,51-0 位表示尾数。

其中可以确定的说,在double中,只有低52位(尾数位部分)才是精确的

所以,在我的redis排行榜设计中,其中低32位为时间戳,高32位为真正的分数,这样只有高32位中的低20位才是有效数位,

因此,这样最多就能最大为支持100w的数据(因为高32位的高12位不能用,精度不准确)

求助:
有什么更好的设计方案吗?实现分数相同,按照时间来排序?

ps:为什么时间戳使用32位,因为 当前时间与2014-01-01 或  2080-01-01 的秒数差 正好是一个int值,也符合项目的周期
加载中
0
AndersZhuo
AndersZhuo
没人关注吗
0
一步萧然01
能不能将double转成字符串,手动指定高位的分数,来使它精确
一步萧然01
回复 @AndersZhuo : 能不能将两个dobule类型拼成字符串,中间用一个标识符分隔,这样可控的范围就变大了吧
AndersZhuo
AndersZhuo
可能你没了解我的问题,我的意思是:但凡在高位12位不是0的话就存在精度问题。 好比我 ,存入reidis的值为: Long的最大值-10 但是我再从redis取出的话,我取到的还是long得最大值
0
朱宏青
朱宏青

我觉得2楼的方法可行

用字符串拼 想拼几个拼几个

长度不够可以用补位

这个需要的实时型不会特别的高 性能应该是没有问题的

AndersZhuo
AndersZhuo
不是很明白,能具体点吗?谢谢
0
wier
wier
我也遇到了和你一样的问题,但是不过的我数据没有100那么大,几十万而已,我现在的问题是,我用zadd的时候,低32位数也是方式时间戳,放进去的时候是10位(小数位),可是拿的时候,有时候会变为12位,这事为何,有研究过么
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部