用redis的zset实现日榜,周榜,月榜
思路:
1.初始化一个月的数据:
/**
* 初始化一个月数据
*/
@Test
public void initMonthData(){
//计算当前时间小时的key
long hour=System.currentTimeMillis()/(1000*60*60);
for(int i=1;i<24*30;i++){
String key="W_hour"+(hour-i);
Random random =new Random();
for(int j=1;j<=26;j++){
stringRedisTemplate.opsForZSet().add(key,"player"+j, random.nextDouble());
}
}
}
2.代码实现:
@RestController
@RequestMapping("/testW")
@Slf4j
public class testW {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@PostConstruct
public void init(){
log.info("定时任务启动");
//定时五秒刷新点赞次数
new Thread(()->this.refreshDataHour()).start();
//定时一小时合并日榜 周榜月榜
new Thread(()->this.refreshData()).start();
}
/**
* 获取日榜前topN
*
*/
@PostMapping("/getDayTopN")
public Set<ZSetOperations.TypedTuple<String>> getDayTopN(int topN) {
return this.stringRedisTemplate.opsForZSet().reverseRangeWithScores("W_day", 0, topN - 1);
}
/**
* 获取周榜前topN
*/
@PostMapping("/getWeekTopN")
public Set<ZSetOperations.TypedTuple<String>> getWeekTopN(int topN) {
return this.stringRedisTemplate.opsForZSet().reverseRangeWithScores("W_week", 0, topN - 1);
}
/**
* 获取月榜前topN
*/
@PostMapping("/getMonthTopN")
public Set<ZSetOperations.TypedTuple<String>> getMonthTopN(int topN) {
return this.stringRedisTemplate.opsForZSet().reverseRangeWithScores("W_month", 0, topN - 1);
}
/**
* 定时五秒刷新点赞次数
*/
public void refreshDataHour(){
while(true){
long hour=System.currentTimeMillis()/(1000*60*60);
Random rand =new Random();
for(int i=1;i<=26;i++){
this.stringRedisTemplate.opsForZSet().incrementScore("W_hour"+hour,"player"+i,rand.nextDouble());
}
try{
Thread.sleep(5000);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
/**
* 定时一小时合并日榜 周榜 月榜
*/
public void refreshData(){
while(true) {
//日榜
this.refreshDay();
//周榜
this.refreshWeek();
//月榜
this.refreshMonth();
try {
Thread.sleep(1000 * 60 * 60);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 日榜
*/
public void refreshDay(){
long hour =System.currentTimeMillis()/(1000*60*60);
//合并一天的key
List<String> keys=new ArrayList<>();
for(int i=1;i<23;i++){
String key="W_hour"+(hour-i);
keys.add(key);
}
//求倒退23小时的并集
this.stringRedisTemplate.opsForZSet().unionAndStore("W_hour"+hour,keys,"W_day");
//设置当前的key 40天过期
for(int i=0;i<24;i++){
String key="W_hour"+(hour-i);
//过期时间设置为40天
stringRedisTemplate.expire(key,40, TimeUnit.DAYS);
}
log.info("日榜合并完成");
}
/**
* 周榜
*/
public void refreshWeek(){
long hour =System.currentTimeMillis()/(1000*60*60);
List<String> keys=new ArrayList<>();
for(int i=1;i<24*7-1;i++){
String key="W_hour"+(hour-i);
keys.add(key);
}
this.stringRedisTemplate.opsForZSet().unionAndStore("W_hour"+hour,keys,"W_week");
log.info("周刷新完成");
}
/**
* 月榜
*/
public void refreshMonth(){
long hour =System.currentTimeMillis()/(1000*60*60);
List<String> keys=new ArrayList<>();
for(int i=1;i<24*30-1;i++){
String key="W_hour"+(hour-i);
keys.add(key);
}
this.stringRedisTemplate.opsForZSet().unionAndStore("W_hour"+hour,keys,"W_month");
log.info("月刷新完成");
}
}
原文地址:https://blog.csdn.net/m0_72410274/article/details/143798879
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!