本文共 1518 字,大约阅读时间需要 5 分钟。
实时排名是网络应用中常见的功能。根据需求不同,大概可以分为以下几类:
作为通用需求,我们必须做如下假设:
基于以上假设,全数据排名就是海量数据处理问题,一般认为内存难以胜任,一般通过数据库(如redis)实现,本文暂不讨论。
这里,我们假设:
那么,问题来了。如何设计数据结构和算法,来满足大批量用户频繁更新榜单情况下的实时排名需求?
曾经看到一个实现,方案如下:
咋一看,由于榜单数据较小,每次更新排序好像可行,但是随着用户基数和更新频度增加,
这个算法无疑跟DB设计把query建立在没有index的table上一样可怕。随着更新频度提升,这个sort操作无疑将成为CPU的噩梦。
低效率的算法不会出bug,但是隐藏在角落偷偷的吃CPU,还很难被发现。
因此,该方案不可取。
经典的有序数据结构,如
貌似可以满足这种需求。
但是,我们知道,平衡二叉树的高效操作是在于快速查找,然而维护一棵树的平衡(插入,删除元素),却是成本很高的操作。
因此,不可取。
这个功能里有一个令人头疼的要求,就是客户端要实时能够查看到排名情况,那么问题来了:
答案是未必。我们知道,排序算法是计算机里面一个比较耗时的操作,频繁的排序更是无法忍受。
比较可行的方案是服务端不排序,只保证榜单记录TopN的数据,把实时排序的任务交给客户端执行。
数据结构定义如下:
type RankInfo struct{ name string // name of this rank element score int // rank score}type RankList struct { list []*RankInfo // unordered top N rank list min *RankInfo // the last one who own the minimum score in list nameMap map[string]*RankInfo // name->rankInfo}
更新积分榜UdateRankList(name, score)的操作流程如下(假设score只会增加不会减少):
至此,排行榜更新完成。不需要排序,不需要支持排序的数据结构,高效的完成榜单维护,perfect。
转载地址:http://fjjl.baihongyu.com/