场景
- 比如某个大型游戏举办大赛,要做一个实时的TopN列表,比如前一百名
解决方案
积分比较稳定并且最大涨/落幅度有限的情况
- 如果说积分比较稳定,并且积分的增长和降落是有上限的(比如每天最多可以打
m
局游戏,并且每次最多涨/落maxp
分),那么还是很好解决的 - 首先在比赛开始前,我们对全量数据(假设数据库表中,积分这个字段是无序的)跑一次全量分析型事务,获得积分前n的所有人的列表,假设第n个人的积分是
k
,那么再获取到积分大于等于k-maxp*m
的人的列表。那么我们可以预期比赛过程中的TopN一定在这些人中产生 - 假设最后一个人是
p
分,那么对于比赛过程中出现的大于等于p
分的人,也加入到list中,以保证这个list确实涵盖了前M名(M就是积分最少为k-maxp*m
的人的数目) - 因为会出现“禁赛”等各种情况,所以可以以1.x倍去获取这个名单,更好的处理方案是按照下文的“积分比较稳定但是最大涨/落幅度无限的情况”去处理
- 还有另一个措施,如果比赛过程中,我们这个list的人数低于一定值,那么就再跑一次全量分析型事务,去补充这个list
- 全量分析任务如何跑?
- 首先对于该全量数据某一时刻的快照,跑一次全量分析事务,拿到前百分之
x
的list - 假设拿到的list中,最后一名的分数
p
,再跑一次全量分析任务,把上一个分析任务过程中新加进来的大于p
分的人加进list中 - 注意,在跑这个新的分析任务时,新出现的,大于
p
分人的也要实时加入list中
- 首先对于该全量数据某一时刻的快照,跑一次全量分析事务,拿到前百分之
积分比较稳定但是最大涨/落幅度无限的情况
- 先获取前
n*k
(比如k是100)的人的list,可以期望TopN都出现在这个list中 - 假设第
n*k
人是p
分,那么对于比赛过程中出现的大于等于p
分的人,也加入到list中,以保证这个list确实涵盖了前n*k
名。当然,对于小于p
分的我们也要清除掉 - 然后如果比赛过程这个list中的人数低于一定值,跑一次全量分析任务,补充这个list
全量计算
- 数据都放在红黑树中,然后每次用户改变自己的积分,就去更改该用户对应的node,然后对该树进行iter,拿到前n个用户,组成list