怎么做网站广告卖钱,阿里云做网站预装环境,做网站的职位叫什么,江门发布最新通告滚动排行榜与一般排行榜的最大区别在于数据的存储和查询方式。在一般排行榜中#xff0c;起始点是固定的#xff0c;例如某一周或某一个月#xff0c;存储和查询时的时间范围也是固定的。而滚动排行榜则不同#xff0c;在滚动排行榜中#xff0c;榜单的取值范围是随着时间… 滚动排行榜与一般排行榜的最大区别在于数据的存储和查询方式。在一般排行榜中起始点是固定的例如某一周或某一个月存储和查询时的时间范围也是固定的。而滚动排行榜则不同在滚动排行榜中榜单的取值范围是随着时间的变化而不断变化的。
对于常用的Redis实现方案来说如果是固定排行榜我们只需要在每个固定的时间点将数据存入相应的Key中查询时只需使用一条命令即可获取。因为在同一时间段内的任何一天都属于同一个周期。
然而对于滚动排行榜比如近7天榜每次查询时都需要对今天及前6天的数据进行聚合计算才能得到最新的排行榜结果。在这种情况下仅仅使用固定的Key无法解决问题因为数据的存储和查询方式都需要特殊处理以确保数据能够快速可用。
具体来说在实现滚动排行榜时我们可以采取以下策略
1.存储方式使用有序集合 Sorted Set存储每个时间点的排行榜数据按照时间顺序存储最新的数据排在前面。
2.数据更新每次有新的数据需要加入排行榜时先将其存入相应的时间点的有序集合中然后根据设定的时间范围删除过期的数据以保持榜单数据的更新和滚动。
3.查询方式为了获得近7天或其他时间范围的排行榜数据需要将对应时间范围内所有的Sorted Set进行聚合操作计算出最终的排名结果。
通过这种存储和查询方式我们能够实现滚动排行榜的功能。但是需要注意在查询时由于需要对多个有序有序进行聚合计算可能会对性能造成一定的影响因此在实际实现中需要进行优化例如增量计算、缓存等手段来提高查询效率。
实现有序集合的第一种方式 1. 同时写n天的滚动榜单
实现一个同步写n天滚动榜单的方法可简单地理解为与固定榜单的实现方式相同。以Redis实现7天滚动方式为例假设我们每天使用礼物排行榜的键值为gift_list_cache:20230101类型选择有序集合 ZSet。每当用户获得一个礼物其对应的价值就会增加最终用于统计排行榜上主播的总收礼情况。
以下是用户ID为Test0001的用户在获得价值为13140的礼物时以及获取排行榜数据的示例命令
// 增加排行榜用户数据
redis.zincrby(gift_list_cache:20231225, 13140, Test0001);1.即每天一个键名将当天的数据写入当天的键中
2.不仅要写入当天的键还要针对接下来的6天进行写入ZINCRBY每次写入操作都按照这个逻辑执行。
类似我们从2023年1月1日开始做滚动榜单那么在1号这一天我们要插入的榜单就是
// 增加1号榜单数据
redis.zincrby(gift_list_cache:20230101, 13140, Test0001);
// 增加2号榜单数据
redis.zincrby(gift_list_cache:20230102, 13140, Test0001);
// 增加3号榜单数据
redis.zincrby(gift_list_cache:20230103, 13140, Test0001);
// 增加4号榜单数据
redis.zincrby(gift_list_cache:20230104, 13140, Test0001);
// 增加5号榜单数据
redis.zincrby(gift_list_cache:20230105, 13140, Test0001);
// 增加6号榜单数据
redis.zincrby(gift_list_cache:20230106, 13140, Test0001);
// 增加7号榜单数据
redis.zincrby(gift_list_cache:20230107, 13140, Test0001);
2号需要插入的榜单数据就是
// 增加2号榜单数据
redis.zincrby(gift_list_cache:20230102, 13140, Test0001);
// 增加3号榜单数据
redis.zincrby(gift_list_cache:20230103, 13140, Test0001);
// 增加4号榜单数据
redis.zincrby(gift_list_cache:20230104, 13140, Test0001);
// 增加5号榜单数据
redis.zincrby(gift_list_cache:20230105, 13140, Test0001);
// 增加6号榜单数据
redis.zincrby(gift_list_cache:20230106, 13140, Test0001);
// 增加7号榜单数据
redis.zincrby(gift_list_cache:20230107, 13140, Test0001);
// 增加8号榜单数据
redis.zincrby(gift_list_cache:20230108, 13140, Test0001);
以此类推那么后面每天都是要插入当天和后面6天的榜单数据那么这样操作到7号的时候7号的当天榜单数据就已经是前7天的滚动榜单了。
具体代码实现
rankScoreUtilManager.addScoreToRank(gift_list_cache:20230101, anchorId, BigDecimal.valueOf(value), EeDateUtil.toDate(eventTime));
rankScoreUtilManager.addScoreToRank(gift_list_cache:20230102, anchorId, BigDecimal.valueOf(value), EeDateUtil.toDate(eventTime));
rankScoreUtilManager.addScoreToRank(gift_list_cache:20230103, anchorId, BigDecimal.valueOf(value), EeDateUtil.toDate(eventTime));
rankScoreUtilManager.addScoreToRank(gift_list_cache:20230104, anchorId, BigDecimal.valueOf(value), EeDateUtil.toDate(eventTime));
rankScoreUtilManager.addScoreToRank(gift_list_cache:20230105, anchorId, BigDecimal.valueOf(value), EeDateUtil.toDate(eventTime));
rankScoreUtilManager.addScoreToRank(gift_list_cache:20230106, anchorId, BigDecimal.valueOf(value), EeDateUtil.toDate(eventTime));
rankScoreUtilManager.addScoreToRank(gift_list_cache:20230107, anchorId, BigDecimal.valueOf(value), EeDateUtil.toDate(eventTime)); 我这里的代码只是为了方便给大家解释逻辑具体榜单的大部分源码可以查看之前的文章Redis实现日榜|直播间榜单|排行榜|Redis实现日榜01但是真实开发的时候最好不要这样写因为这样写并不能保证7个榜单同时插入的原子性最好把6个榜单的key都写在lua脚本中同步执行。
优点 1. 实现简单获取数据也简单直接获取即可使用。
缺点 1. 每次写入需要写入多个键名。不将部分写入失败作为缺点是因为其他方案在不严谨的情况下也可能存在此问题。如果只是实现7天榜单且不想浪费过多精力可以采用此方案。但是如果天数较多比如30天滚动榜单则显然不适合。后续还会介绍另外两种滚动榜单的实现方式。