严格排行榜严格排行榜必须满足大家的排序才具有实际意义,简单来说,即使两个人的分数相同,也要先排序最后。如果活动周期在92天之内,那么我们可以用200w加上活动结束时间作为数字A来保证排行榜的顺序是正确的。在一个大型活动中,比如一个大奖,第10名和第11名,可能的奖金数额从几万到几千不等。这个时候,我们在处理的时候一定要小心。我们希望保持公平的排行榜。为了满足这样的排行榜,我们需要在分数后面加上一个时间戳相关的系数。例如:用户a在14:00获得100积分,用户b在14:20获得100积分。那么根据排行榜的规则,用户a应该排在用户b之前。但是我们在排序的时候,不能直接把时间加到分数上,否则排序会倒过来。这时候我们就需要用一个足够大的数A来减去时间戳,并且要保证在整个活动过程中位数不会发生变化。改变。首先我们要了解一个redis的排序。redis的zset中score值为double类型,精度只有16位。实际上,当存储一个16位整数9999999999999999时,就会变成17位的10000000000000000,超过17位就会变成科学记数法1e+17。活动期间,我们需要保证用户的积分不能丢失,所以一定要保证在16以内。一个用户的最高粉丝数是5000w。如果在一次活动中,所有的用户都能保证所有的用户都给他积分,那么可能就是亿级别的,但实际上按照之前的活动量,最多也能达到千万级别。这个时候我们按照1亿来计算,长度要保证是9位,然后要复用的剩余时间戳的精度要保证是7位,也就是说要保证数字足够大,可以减去整个活动期间的时间,戳记开始时间和结束时间都是7位数字。首先保证号码A-结束时间是7位数字,那么我们需要加上这个结束时间+1000000(一百万)得到号码A,这样至少可以保证时间戳系数的位数活动结束前不会更改为7位数字。那么我们需要保证号码A-事件开始时间也是一个七位数,也就是说开始时间和结束时间之间的跨度只能是900w,一旦超过900w,那么号码A减去开始时间会得到一个8位数的编号。但是100w是一个临界点。我们加上100w和结束时间得到A号,由于事件结束时间的延长,效果可能变成结束时间+99w得到A号。这时候,事件结束的得分系数为位数变成了6,就是一场灾难。所以我们把100w扩大到200w,也相应的增加了(100w/3600/24=11)天到活动的结束时间。但是由此产生的效果将activity的span周期缩短为800w秒,也就是(8000000/86400=92)天。所以,如果活动周期在92天之内,那么我们可以用200w加上活动结束时间作为数字A来保证排行榜的正确排序。
