游戏模块思路设计

============================排行榜============================


玩家数据刷新时: 若为定时刷新的榜信息,则生成并更新玩家榜数据到module中的缓存。缓存有五分钟时间差,若玩家数据刷新的时候超过时间差,则发送到db进程中放入到db的cache中并清理module中的缓存,db的cache也有五分钟时间差,若module发送数据到db的时候超过时间差,则把db的cache中的数据更新到数据库的临时表中并清除db中的缓存。

                               若为实时刷新的榜信息,直接把玩家数据更新到db进程中的正式数据库中,并排序

Master中:             主要提供给所有玩家排行榜的信息数据,读取db进程中数据库中的正式表数据(并非cache)
                               若定时器时间到了,则把module中的缓存数据发送到db进程中并清理module中的缓存,db的cache也有五分钟时间差,若module发送数据到db的时候超过时间差,则把cache中的数据更新到数据库的临时表中并清除db中的缓存。最后,db进程将缓存数据更新到临时表中,内存数据库中排序,同时将排序结果更新到正式表中

排序算法:      依赖于sqlite的内存数据库排序

实时排行榜就直接游戏里内存实时排序:

用于排名的分数区间不大,也就是 0 分到 5000 分。而参与排名的人数众多,数以百万计。对百万用户做插入排序,每个插入即使是 O(N) 的也不可接受。可事实是大量玩家的分数相同,都是并列排名的。所以我们只需要做 5000 个桶,每个桶里仅记录这个分数有多少个人就可以了。
当玩家分数变迁,把原来的桶减一,新的桶加一。这个操作就是 O(1) 的。
而排行榜的查询仅需要把当前分数靠前的桶累加,就能获知查询者的名次。对于上百万玩家,看到哪些人和你并列的人的名字是没有意义的。这个查询虽然是 O(n) 复杂度,但 n 只有区区 5000 ,还可以做 cache 以应对查询频率远高于更新频率的情况。
真正需要精确知道人名的是榜单的前 200 个人,而对前 200 个人做插入排序也很快,所以并不会造成性能问题。
我们在系统的单点做排行榜的维持,完全没有外部数据库操作,它只是一小段操作普通内存结构的 c 代码。而这个单点远远成为不了整个系统的热点。
我们在系统临时退出时,把已经排好的榜单落地,下次启动的时候恢复。但也不必完全信任落地的数据,可以用离线脚本检索整个数据库重新生成一份正确的榜单。所以数据库中的榜单只是被 cache 起来而已,系统运行期间是不需要写入数据库的,也不用担心数据丢失。

猜你喜欢

转载自blog.csdn.net/Hahaha_Val/article/details/81514902