使用Redis实现热搜功能

Redis热搜

原理

使用redis实现热搜的原理就是维护一个zset集合,然后使用score作为当前搜索词的搜索量,score越高的搜索词就说明该搜索词热度越高。然后在每天凌晨十二点对热搜榜进行维护,将前十名热搜删除,防止热搜霸榜(这里有更好的热搜榜单维护方式,感兴趣的小伙伴可以自己了解一下)。

数据类型

使用redis中的zset类型,主要使用的方法有两个:

zincrby: 对zset中的元素score进行自增自减操作

zrevrange:降序获得zset中的热搜榜单

写到这里大家应该已经明白了,当用户搜索时,使用zincrby方法对搜索词的score进行自加操作。查询热搜榜单时,使用zrevrange获得热搜前几名的搜索词。

redis操作简单实现

首先创建一个zset集合

现在我们向zset中添加几条数据

假设现在搜索词为5的数据被五个用户分别搜索了五次,使用zincrby模拟该操作。

现在执行查询操作,查出热榜上前五的搜索词,使用zrevrange模拟该操作。

至此理论成立,开始实践!

实操

封装方法

首先在redis的工具类中封装zincrby和zrevrange两个方法

java 复制代码
	public static void zincrby(String key , Object value , double score){
		//不管有没有该数据,先add一边,如果有该语句不执行,如果没有就创建一条数据。
		//使用add会覆盖原来score
        redisTem.opsForZSet().addIfAbsent(key , value , 0);
        //获取原来的score
        Double score1 = redisTem.opsForZSet().score(key, value);
        //自增
        redisTem.opsForZSet().add(key , value , score1+ score);
    }

	public static Set zrevrange(String key , long start , long end){
        return redisTem.opsForZSet().reverseRange(key , start , end);
    }

执行方法

然后在用户执行搜索操作的时候对搜索词的score进行更改

java 复制代码
//condition是搜索条件
RedisTemplateUtil.zincrby(RedisConstants.HOTSELECT , condition , 1);

写一下查询接口

java 复制代码
	@GetMapping("/getHotSelect")
    @ApiOperation("获取热搜榜单")
    @ApiImplicitParam(name = "count" , value = "获取数量")
    public Result getHotSelect(int count){
        if(count <= 0){
            return Result.BAD_REQUEST();
        }
        return videoService.getHotSelect(count);
    }

service:

java 复制代码
	@Override
    public Result getHotVideo(int count) {
        Set zrevrange = RedisTemplateUtil.zrevrange(RedisConstants.HOTVIDEO, 0, count - 1);
        return Result.OK(zrevrange);
    }

最后使用springboot的定时任务对热搜榜单进行维护

笔者这里写的是每天凌晨将前十个热搜删除,这个方法写的比较烂,大家可以自己查询学习一下比较好的热搜算法,对热搜进行维护。(可以将这些数据放入mysql统一管理或者使用一个变量作为热度因子对热搜真实热度进一步统计)

java 复制代码
	@Scheduled(cron = "0 0 0 * * *")
    private void deletehotSelect(){
        for(int i = 0;i<10;i++){
            redisTem.opsForZSet().popMax(RedisConstants.HOTSELECT);
        }
    }

(完)

相关推荐
伤不起bb3 小时前
Redis 哨兵模式
数据库·redis·缓存
迪迦不喝可乐3 小时前
Redis 知识点一
redis·缓存
卑微的Coder3 小时前
Redis Set集合命令、内部编码及应用场景(详细)
java·数据库·redis
2501_915373883 小时前
Redis线程安全深度解析:单线程模型的并发智慧
数据库·redis·安全
呼拉拉呼拉3 小时前
Redis知识体系
数据库·redis·缓存·知识体系
霖檬ing3 小时前
Redis——主从&哨兵配置
数据库·redis·缓存
CrissChan3 小时前
Pycharm 函数注释
java·前端·pycharm
启航挨踢4 小时前
java学习电子书推荐
java
wgslucky4 小时前
Dubbo报错:module java.base does not “opens java.lang“ to unnamed module
java·开发语言·dubbo
DougLiang5 小时前
关于easyexcel动态下拉选问题处理
java·开发语言