游戏里经常有涉及用户排行榜(金币消费排行榜),怎么设计一个良好的排行榜。

个人记录:2018年,工作的第6到7个年头。
重点研究自己不太擅长的技术:分布式、高并发、大数据量、数据库优化、高性能、负载均衡等。
刷题是一种态度,是一种好习惯。
我刷题,我骄傲。


题目:游戏里 经常有涉及 用户排行榜(金币消费排行榜),怎么设计一个良好的排行榜。
诸如 几千万的用户量, 每个用户消费金币的频率也比较高。  排行榜 从数据采集 到 排行 一整套下来。有什么样的设计方案。
问题出处:http://ifeve.com/question/%e6%b8%b8%e6%88%8f%e9%87%8c-%e7%bb%8f%e5%b8%b8%e6%9c%89%e6%b6%89%e5%8f%8a-%e7%94%a8%e6%88%b7%e6%8e%92%e8%a1%8c%e6%a6%9c%ef%bc%88%e9%87%91%e5%b8%81%e6%b6%88%e8%b4%b9%e6%8e%92%e8%a1%8c%e6%a6%9c%ef%bc%89/


个人看法
第1次上线,系统全量统计,取TOP1000。
后续,白天,每小时近实时统计前TOP10000,刷新TOP1000。理由是,正常的消费,当天的TOP1000,99.9%的概率,存在于前一天的TOP10000。
(如果不放心,当用户一次消费大于一定金额,比如10000的时候,把此用户id加入每小时近实时统计)
夜间,全量统计一次。


如果数据量特别大,每周全量统计一次。
采用递增的统计方式,第1次上线全量统计,后续有消费行为的时候,发送一个MQ消息,累加到数据库。


TOP1000和TOP10000等数据,缓存到Redis中。


user amount
1   1000
2   900
3   800


全量统计可能没有必要:如果按天统计,过去消费记录,统计之后,几乎不会再变化。只按天统计,累加也行。


总结:定期全量统计,小时统计+MQ消息累加+缓存。


建议:
上线统计所有,比如,截止到前1天1000消费。
每天,统计当天的,存到数据库。
每天第1次查询,取TOP10000缓存到Redis,取TOP1000展示。
如果TOP10000,有消费MQ,实时累加,缓存到Redis。
每天,夜间继续统计前一天的。


是否有必要统计所有天数的,核对数据,看情况。


网友看法
hellocrest
对于数据量较大,并且易变的数据,可以将数据放入缓存中。通过缓存来实现排行榜功能,同时,还要保证缓存与db中的数据一致。


梦朝思夕
我建议,可以分地区,这样一个地区内的数据先排序好,这样就可以减少排序时间,再将排序的地区,进行top K算法,获取先N个。
假设我们正在开发一个游戏,需要设计一个金币事件,当玩家进行某些操作时,金币数量会发生变化。 首先,需要定义一个金币类 Coin,该类包含以下属性和方法: ```javascript class Coin { constructor(amount) { this.amount = amount; // 金币数量 } // 增加金币数量 add(amount) { this.amount += amount; } // 减少金币数量 reduce(amount) { this.amount -= amount; } // 获取金币数量 getAmount() { return this.amount; } } ``` 接下来,需要设计一个金币事件类 CoinEvent,该类包含以下属性和方法: ```javascript class CoinEvent { constructor(coin, amount) { this.coin = coin; // 金币对象 this.amount = amount; // 金币数量 } // 执行金币事件 execute() { // 判断金币数量是否足够 if (this.coin.getAmount() >= this.amount) { this.coin.reduce(this.amount); // 减少金币数量 console.log(`金币减少了 ${this.amount},当前剩余 ${this.coin.getAmount()} 个金币`); } else { console.log(`金币数量不足,当前剩余 ${this.coin.getAmount()} 个金币`); } } } ``` 最后,当玩家进行某些操作时,可以创建一个 CoinEvent 对象,然后调用其 execute 方法来执行金币事件。比如: ```javascript const coin = new Coin(100); // 初始化金币数量为 100 const coinEvent = new CoinEvent(coin, 20); // 创建一个金币事件,减少 20 个金币 coinEvent.execute(); // 执行金币事件 ``` 以上是一个简单的金币事件的设计和实现,可以根据具体需求进行修改和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值