Java 使用 Redis 实现微博热搜功能

news2024/12/13 5:19:56

在社交平台上,热搜功能是一个非常重要的组成部分。它展示了当前最热门的话题,帮助用户迅速了解最受关注的事件。在微博等平台上,热搜榜单通常是实时变化的,可能会根据用户的互动数据(如搜索频次、点赞量、评论数等)动态调整。

Redis 是一个高性能的键值存储系统,通常用于缓存和实时数据存储,特别适用于实现类似热搜榜单这样的功能。本文将通过 Java 结合 Redis 实现一个简化版的微博热搜功能,展示如何使用 Redis 提供的高效数据结构,如 SortedSet(有序集合)来维护热搜榜单。

 热度的计算方式,不同的产品的热度计算方式不同:

                例如:热度=评论数+转发数+点赞数 

                          热度=搜索量+点击量

热搜排行榜可以分为:当前小时的热搜榜,当天的热搜榜,当月的热搜榜,当前周的热搜榜等等。

       思路: 一般情况下,我们按照存储每个小时的小时榜,为最小单位。  同理,当天的热搜榜,就是这一天24小时的小时榜合并后的榜单。当月的热搜榜就是,这个月每天的热搜榜合并后的榜单。

1. Redis 数据结构介绍

在实现热搜功能时,Redis 提供的 SortedSet(有序集合)是非常合适的。SortedSet 会根据分数(score)对成员(member)进行排序,适用于我们要根据热度(例如搜索频次、点赞数等)排序展示的场景。

  • SortedSet(zset):是一个有序的集合,每个元素都有一个分数(score),Redis 会自动根据分数对元素进行排序。适合实现需要排序的场景,如热搜榜单、排行榜等。

2.当前小时的key的设定思路:

        1.使用当前的时间戳来生成唯一的 key,通常使用 YYYY-MM-DD-HH 作为 key 的格式,这样每天每小时的数据都会有独立的 key。

        例如:当前时间为 2024-12-10 07:25:21,那么对应的 key 为 2024-12-10-07

        2.当前时间的毫秒的时间(T),当前小时唯一key=T/1000*60*60;

        例如:当前时间为2024-12-10 16:10:40=1733818240000  ,那么对应的key就是:1733818240000 /1000*60*60=481,616

        以上两种方式,都可以获取到当前时间的唯一的key。

3.代码实现

1. 引入依赖

在你的 pom.xml 中加入以下依赖来使用 Redis 和 Jedis:

<dependencies>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>4.2.3</version>
    </dependency>
</dependencies>

 主要需要实现的功能:热搜的小时榜,天榜,月榜的榜单的实现。

 首先编写redis的基本操作的工具类:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.Set;

public class RedisUtil {
    private static JedisPool pool;

    static {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(50);
        config.setMaxIdle(10);
        config.setMinIdle(5);
        config.setTestOnBorrow(true);
        pool = new JedisPool(config, "localhost", 6379);  // Redis 地址
    }

    public static Jedis getJedis() {
        return pool.getResource();
    }

    public static void close(Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }

    public static void incrementSearchCount(String key,String topic) {
        Jedis jedis = getJedis();
        try {
            // 使用 Redis 的 ZINCRBY 命令递增话题的热度
            jedis.zincrby(key, 1, topic);
        } finally {
            close(jedis);
        }
    }

    public static Set<String> getTopSearch(int topN) {
        Jedis jedis = getJedis();
        try {
            // 使用 Redis 的 ZREVRANGE 命令获取热搜榜单
            return jedis.zrevrange("hot_search", 0, topN - 1);
        } finally {
            close(jedis);
        }
    }
}

        热搜的增加,每次都是单个增加的,此处不做解释。我们主要研究,如何查询,小时榜,天榜,月榜的数据。 

       具体代码如下:

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 更新天的热搜数据
     */
    public void updateDaySearch(){
        long hour = System.currentTimeMillis()/(1000*60*60);
        //小时key的前缀
        String hourPrefix = "search:hour";
        //天的key
        String dayPrefix = "search:day";
        //计算最近24小时的key的集合
        ArrayList<Object> dayKeys = new ArrayList<>();
        //统计近24小时的key的集合
        for (int i = 1; i < 23; i++) {
            String key = hourPrefix+(hour-i);
            dayKeys.add(key);
            //设置当天的key 40天过期,防止资源的浪费
            redisTemplate.expire(key,40, TimeUnit.DAYS);
        }
        //将近24小时的key的值进行合并
        //(redisTemplate.opsForZSet()。unionAndStore(a,b,c);把a,b 两个zset合并储存到c集合中)
        redisTemplate.opsForZSet().unionAndStore(hourPrefix+hour,dayKeys,dayPrefix);
        log.info("*********************进行天数据的更新************************");
    }

    public void updateMonthSearch(){
        long hour = System.currentTimeMillis()/(1000*60*60);
        //小时key的前缀
        String hourPrefix = "search:hour";
        //天的key
        String monthPrefix = "search:day";
        //计算最近24小时的key的集合
        ArrayList<Object> monthKeys = new ArrayList<>();
        //统计近24小时的key的集合
        for (int i = 1; i < 24*30-1; i++) {
            String key = hourPrefix+(hour-i);
            monthKeys.add(key);
        }
        //将近30天的key的值进行合并
        redisTemplate.opsForZSet().unionAndStore(hourPrefix+hour,monthKeys,monthPrefix);
        log.info("***************进行月数据的更新*********************");
    }

    /**
     * 更新最近7天的数据
     */
    public void updateWeekSearch(){
        long hour = System.currentTimeMillis()/(1000*60*60);
        //小时key的前缀
        String hourPrefix = "search:hour";
        //周的key
        String weekPrefix = "search:week";
        //计算最近24小时的key的集合
        ArrayList<Object> weekKeys = new ArrayList<>();
        //统计近24小时的key的集合
        for (int i = 1; i < 24*7-1; i++) {
            String key = hourPrefix+(hour-i);
            weekKeys.add(key);
        }
        //将近30天的key的值进行合并
        redisTemplate.opsForZSet().unionAndStore(hourPrefix+hour,weekKeys,weekPrefix);
        log.info("************进行周数据的更新******************");
    }

    /**
     * 定时器每小时调用一次次方法进行,小时榜,天榜,周榜,月榜的更新
     */
    public void updateAllSearch(){
        //TODO 此方法建议使用定时框架,quartz ,xxl-job等进行定时调用
        updateDaySearch();
        updateWeekSearch();
        updateMonthSearch();
    }

4. 优化和扩展

  1. 热搜榜单过期策略:可以设置 Redis 中有序集合的过期时间,定期清理不再热门的关键词。
  2. 多维度排序:除了搜索次数外,可以根据时间窗口(例如过去一小时、一天内的搜索量)来做更加复杂的排序。
  3. 高并发优化:为了避免频繁的 Redis 操作影响性能,可以考虑将热搜数据批量更新或者使用消息队列来异步处理。

总结

通过以上的实现,我们展示了如何使用 JavaRedis 来实现一个简单的微博热搜功能。通过 Redis 的有序集合,我们能够高效地记录和排序搜索关键词的热度,并在用户请求时实时返回当前最热门的话题。

这种基于 Redis 的热搜功能不仅适用于微博,实际上可以广泛应用于各种需要统计热门话题或关键词的场景,如新闻网站、视频平台等。

希望本文对你理解 Redis 和 Java 的结合使用有所帮助,如果有任何问题或进一步的优化建议,欢迎在评论区讨论!

点点关注,点点赞呀,持续更新有用的知识............

 

 

 

        

      

    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2258584.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《庐山派从入门到...》IDE启动

《庐山派从入门到...》IDE启动 《庐山派从入门到...》IDE启动 IDE&#xff08;Integrated Development Environment&#xff09;&#xff0c;即集成开发环境&#xff0c;是一种软件应用程序&#xff0c;旨在为软件开发人员提供一个全面的工具集合&#xff0c;以便可以更高效地编…

打电话玩手机识别-支持YOLO,COCO,VOC格式的标记,超高识别率可检测到手持打电话, 非接触式打电话,玩手机自拍等

打电话玩手机识别-支持YOLO&#xff0c;COCO&#xff0c;VOC格式的标记&#xff0c;超高识别率可检测到手持打电话&#xff0c; 非接触式打电话&#xff0c;玩手机自拍等1275个图片。 手持打电话&#xff1a; 非接触打电话 玩手机 数据集下载 yolov11:https://download.csdn…

【智体OS】官方上新发布智体电视:基于rtpc和rttouchpad实现智体电视的手机遥控-可安装任意PC应用用于智体电视

【智体OS】官方上新发布智体电视&#xff1a;基于rtpc和rttouchpad实现智体电视的手机遥控-可安装任意PC应用用于智体电视 dtns.network是一款主要由JavaScript编写的智体世界引擎&#xff08;内嵌了three.js编辑器的定制版-支持以第一视角浏览3D场馆&#xff09;&#xff0c;…

Flink+Paimon实时数据湖仓实践分享

随着 Paimon 近两年的推广普及&#xff0c;使用 FlinkPaimon 构建数据湖仓的实践也越来越多。在 Flink 实时数据开发中&#xff0c;对于依赖大量状态 state 的场景&#xff0c;如长周期的累加指标计算、回撤长历史数据并更新等&#xff0c;使用实时数仓作为中间存储来代替 Flin…

Stable Diffusion本地部署:从零开始的完整指南

1、引言 Stable Diffusion是计算机视觉领域的一个生成式大模型&#xff0c;能够进行文生图&#xff08;txt2img&#xff09;和图生图&#xff08;img2img&#xff09;等图像生成任务。它利用深度学习技术&#xff0c;特别是RealisticVision v2.0模型&#xff0c;能够创造出接近…

鸿蒙元服务上架

鸿蒙元服务上架 一、将代码打包成 .app 文件1. 基本需求2. 生成密钥和证书请求文件3. 申请发布证书4. 申请发布Profile5. 配置签名信息6. 更新公钥指纹7. 打包项目成 .app 文件 二、发布元服务1. 进入应用信息页面2. 上传软件包3. 配置隐私协议4. 配置版本信息5. 提交审核&…

【论文阅读】PRIS: Practical robust invertible network for image steganography

内容简介 论文标题&#xff1a;PRIS: Practical robust invertible network for image steganography 作者&#xff1a;Hang Yang, Yitian Xu∗, Xuhua Liu∗, Xiaodong Ma∗ 发表时间&#xff1a;2024年4月11日 Engineering Applications of Artificial Intelligence 关键…

day2 数据结构 结构体的应用

思维导图 小练习&#xff1a; 定义一个数组&#xff0c;用来存放从终端输入的5个学生的信息【学生的信息包含学生的姓名、年纪、性别、成绩】 1>封装函数 录入5个学生信息 2>封装函数 显示学生信息 3>封装函数 删除第几个学生信息&#xff0c;删除后调用显示学…

特征交叉-CAN学习笔记代码解读

一 核心模块coaction 对于每个特征对(feature_pairs)weight, bias 来自于P_inductionP_fead是MLP的input 举个例子&#xff1a;如果是用户ID和产品ID的co-action&#xff0c;且产品ID是做induction&#xff0c;用户ID是做feed。 step1 用户ID/产品ID都先形成一个向量&#xf…

EfficientNet与复合缩放理论(Compound Scaling Theory) 详解(MATLAB)

1.EfficientNet网络与模型复合缩放 1.1 EfficientNet网络简介 1.1.1 提出背景、动机与过程 EfficientNet是一种高效的卷积神经网络&#xff08;CNN&#xff09;&#xff0c;由Google的研究团队Tan等人在2019年提出。EfficientNet的设计目标是提高网络的性能&#xff0c;同时减…

SQL语句在MySQL中如何执行

MySQL的基础架构 首先就是客户端&#xff0c;其次Server服务层&#xff0c;大多数MySQL的核心服务都在这一层&#xff0c;包括连接、分析、优化、缓存以及所有的内置函数&#xff08;时间、日期、加密函数&#xff09;&#xff0c;所有跨存储引擎功能都在这一层实现&#xff1…

开源低代码平台-Microi吾码-表单控件数据源绑定配置

表单控件数据源绑定配置 平台简介普通数据源数据源引擎Sql数据源通过其它字段来动态绑定数据源关于绑定数据源后的显示字段和存储字段 平台简介 技术框架&#xff1a;.NET8 Redis MySql/SqlServer/Oracle Vue2/3 Element-UI/Element-Plus平台始于2014年&#xff08;基于Av…

Y3编辑器文档4:触发器1(对话、装备、特效、行为树、排行榜、不同步问题)

文章目录 一、触发器简介1.1 触发器界面1.2 ECA语句编辑及快捷键1.3 参数设置1.4 变量设置1.5 实体触发器1.6 函数库与触发器复用 二、触发器的多层结构2.1 子触发器&#xff08;在游戏内对新的事件进行注册&#xff09;2.2 触发器变量作用域2.3 复合条件2.4 循环2.5 计时器2.6…

Redis原理—4.核心原理摘要

大纲(9870字) 1.Redis服务器的Socket网络连接建立 2.Redis多路复用监听与文件事件模型 3.基于队列串行化的文件事件处理机制 4.完整的Redis Server网络通信流程 5.Redis串行化单线程模型为什么能高并发 6.Redis内核级请求处理流程与原理 7.Redis通信协议与内核级请求数据…

轻量级日志管理平台:Grafana Loki搭建及应用(详细篇)

前言 Grafana Loki是Grafana Lab团队提供的一个水平可扩展、高可用性、多租户的日志聚合系统&#xff0c;与其他日志系统不同的是&#xff0c;Loki最初设计的理念是为了为日志建立标签索引&#xff0c;而非将原日志内容进行索引。 现在目前成熟的方案基本上都是&#xff1a;L…

【规范一】JAVA静态代码规范

1.规范的划分 将Java代码规范分为 风格规范 和 质量规范 &#xff0c;主要是因为这两种规范关注的方面不同&#xff0c;各自解决的问题也不同。下面详细解释为什么需要将代码规范分为这两种 1.1 风格规范&#xff08;Coding Style Guidelines&#xff09; 风格规范主要关注代码…

Angular由一个bug说起之十二:网页页面持续占用CPU过高

随着网络日益发达&#xff0c;网页的内容也更加丰富&#xff0c;形式也更加多样化。而随之而来的性能问题也不容小觑。这篇文章我会根据我在实践中遇到的一个问题来总结&#xff0c;我在面对性能问题的一些解决步骤&#xff0c;希望能对大家有所启发。 查找问题原因 我接触的…

WordPress全能CDN插件_自动刷新预热_缓存优化|国内国外集成CDN配置

WordPress全网独家原创CDN插件 自动刷新预热 缓存优化 国内国外集成CDN配置 支持白山云 cdnfly Cloudflare PS:目前国内集成了CDNfly,白山云国外集成了Cloudflare,更新手动刷新&#xff0c;全站刷新&#xff0c;优化提交线程&#xff0c;根据网友建议适配阿里云&#xff0c;le…

唇形同步视频生成工具:Wav2Lip

一、模型介绍 今天介绍一个唇形同步的工具-Wav2Lip&#xff1b;Wav2Lip是一种用于生成唇形同步&#xff08;lip-sync&#xff09;视频的深度学习算法&#xff0c;它能够根据输入的音频流自动为给定的人脸视频添加准确的口型动作。 &#xff08;Paper&#xff09; Wav2Lip模型…

【汽车】-- 燃油发动机3缸和4缸

3缸和4缸燃油发动机是小轿车常见的发动机配置。以下从结构特点、性能、经济性等方面对两者进行对比&#xff0c;并分析优缺点及使用注意事项&#xff1a; 1. 结构与运行原理 3缸发动机 特点&#xff1a;少一个气缸&#xff0c;内部零部件更少&#xff0c;整体结构更紧凑。优点…