用redis的zset实现日榜,周榜,月榜

news/2024/11/16 18:27:43 标签: redis, 数据库, java

思路:

请添加图片描述

1.初始化一个月的数据:

java"> /**
     * 初始化一个月数据
     */
    @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.代码实现:

java">@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("月刷新完成");
    }
}

请添加图片描述
请添加图片描述
请添加图片描述


http://www.niftyadmin.cn/n/5754503.html

相关文章

LabVIEW大数据处理

在物联网、工业4.0和科学实验中&#xff0c;大数据处理需求逐年上升。LabVIEW作为一款图形化编程语言&#xff0c;凭借其强大的数据采集和分析能力&#xff0c;广泛应用于实时数据处理和控制系统中。然而&#xff0c;在面对大数据处理时&#xff0c;LabVIEW也存在一些注意事项。…

博睿数据登顶中国应用性能管理及可观测性APMO市场份额第一!

近日&#xff0c;全球领先的IT市场研究和咨询公司IDC发布《中国IT智能运维软件产品市场跟踪报告&#xff0c;2024H1》&#xff0c;此次IDC将原有IT统一运维软件报告即ITUO报告升级为IT智能运维软件报告即ITAO报告&#xff0c;以反映越来越多的运维软件在不断加持AI能力&#xf…

LeetCode74. 搜索二维矩阵(2024冬季每日一题 6)

给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a; 每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target &#xff0c;如果 target 在矩阵中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。…

UEFI Shell命令(二)

一、Shell 命令行选项 ​-b, -break 每页输出后暂停一会&#xff0c;即分页输出 -q, -quiet 抑制所有的输出 -sfo 标准格式输出 -t, -terse 简洁的输出 -v, -verbose 详细的输出 -&#xff1f; 帮助 二、特殊Shell命令 1、attrib 显示或更改文件或目录的属性 [a | -a] 设置…

【英特尔IA-32架构软件开发者开发手册第3卷:系统编程指南】2001年版翻译,2-24

文件下载与邀请翻译者 学习英特尔开发手册&#xff0c;最好手里这个手册文件。原版是PDF文件。点击下方链接了解下载方法。 讲解下载英特尔开发手册的文章 翻译英特尔开发手册&#xff0c;会是一件耗时费力的工作。如果有愿意和我一起来做这件事的&#xff0c;那么&#xff…

vue3 + vite 进行axios请求封装及接口API的统一管理

前言 在Vue 3项目中使用Vite进行开发时&#xff0c;对axios进行请求封装以及统一管理接口API是非常常见的做法。这不仅可以提高代码的复用性和可维护性&#xff0c;还能统一处理请求和响应&#xff0c;管理错误处理逻辑等。下面是一个详细的步骤和示例代码&#xff0c;来说明如…

PyAEDT:Ansys Electronics Desktop API 简介

在本文中&#xff0c;我将向您介绍 PyAEDT&#xff0c;这是一个 Python 库&#xff0c;旨在增强您对 Ansys Electronics Desktop 或 AEDT 的体验。PyAEDT 通过直接与 AEDT API 交互来简化脚本编写&#xff0c;从而允许在 Ansys 的电磁、热和机械求解器套件之间无缝集成。通过利…

EHOME视频平台EasyCVR多品牌摄像机视频平台监控视频编码H.265与Smart 265的区别?

在视频监控领域&#xff0c;技术的不断进步推动着行业向更高效、更智能的方向发展。特别是在编码技术方面&#xff0c;Smart 265作为一种新型的视频编码技术&#xff0c;相较于传统的H.265&#xff0c;有明显优势。这种技术的优势在EasyCVR视频监控汇聚管理平台中得到了充分的体…