Redis 之 ZSET 实战应用场景,持续更新!

前言

大白话介绍 Redis 五大基本数据类型之一的 ZSET 开发中常见的应用场景

ZSET 介绍

  • ZSET 与 SET 相同点:都是是 String类型元素的集合,且不允许重复的成员
  • ZSET 与 SET 不同点:ZSET 每个元素都会关联一个 Double 类型的分数,Redis
    通过分数来为集合中的成员进行从小到大的排序。ZSET 的成员是唯一的,但分数 score 却可以重复

ZSET 应用场景

  1. 基于 ZSET 实现的滑动窗口限流
  2. 直播间送礼物排名榜
  3. 网易新闻、百度热搜,实时新闻、文章类的需求

ZSET 常用 Redis 指令介绍

直接对着控制台简单实操一下,方便大家理解。熟悉指令的读者可自行跳过本章节
在这里插入图片描述

zremrangeByScore

移除 key 为 ranking 且 source 值在 (0,1) 区间的所有数据,返回结果是 3,代表成功移除 3 条数据

zremrangeByScore ranking 0 1

zremrangeByScore ranking 0 1

zcard

统计 key 为 ranking 中剩余元素的个数,移除 3 条数据还剩一条,因此返回结果是 1

zcard ranking

在这里插入图片描述

zrevrangeByScore

ZSET 分页查询,LIMIT 对满足条件的成员列表进行分页。一般会配合 “+inf” 或者 “-inf” 来表示最大值和最小值。这个最大最小值针对于 score 而言。

zrevrangeByScore ranking +inf -inf LIMIT 0 2

在这里插入图片描述

zincrby

没有当前成员则新增、有则修改分数

zincrby ranking 666 "无名黑马"

在这里插入图片描述

zadd

往 ZSET 中添加元素

zadd ranking 5 "王老五"

在这里插入图片描述

基于 ZSET 实现的滑动窗口 Lua 脚本

实现步骤:

  1. 删除固定时间窗口之前的所有的数据
  2. 统计剩余元素数量
  3. 剩余元素数量超过设定阈值,返回 0,没超过返回 1
-- 1. 依赖 redis 中的 zset 类型,zremrangeByScore命令含义:移除0ARGV[1]的所有数据
redis.call('zremrangeByScore', KEYS[1], 0, ARGV[1])
-- 2. 统计剩余元素数量
local res = redis.call('zcard', KEYS[1])
-- 3. 剩余元素是否超过阈值
if (res == nil) or (res < tonumber(ARGV[3])) then-- 4.没超过阈值 zaddredis.call('zadd', KEYS[1], ARGV[2], ARGV[4])return 1
elsereturn 0
end

redis.call()表示执行当前的 redis 指令,比方说 redis.call(‘zremrangeByScore’, ‘ranking’, 0, 1) 等价于执行 zremrangeByScore ranking 0 1 这么一条命令。 Java 代码调用代码如下。

 /*** unit秒内只能通过qps个请求*/public Object acquire(String key, Integer unit, String qps) {long now = System.currentTimeMillis();Assert.notNull(unit, "unit不能为 null");/*** --KEYS[1]: 限流 key* --ARGV[1]: 限流窗口(String.valueOf(now - 1000 * unit))* --ARGV[2]: 当前时间戳(String.valueOf(now))* --ARGV[3]: 阈值 qps* --ARGV[4]: score 对应的唯一value(String.valueOf(now))*/return redisTemplate.execute(redisScript,Arrays.asList(defaultKeyPrefix + key),String.valueOf(now - 1000 * unit),String.valueOf(now),qps == null ? defaultQps : qps,String.valueOf(now));}

基于 ZSET实现的热搜文章

也是利用ZSET范围有序查询的特性实现,现在初始化一波数据如下图,先用 Redis 命令演示一波。后续用 Java 代码实现。

在这里插入图片描述
现在需要查最新的 2 条热点数据,执行如下指令。由于 ZSET是有序集合且查询的结果默认是倒序输出,因此最新的俩条数据就被查到了。结果如下

zrevrangeByScore article +inf -inf LIMIT 0 2

在这里插入图片描述
查第二页的数据怎么查?记录每一次查询的最大值,当做下一次查询的游标即可查到第二页数据。

zrevrangeByScore article 20231207 -inf LIMIT 0 2

在这里插入图片描述

对应配套 java 代码

因为 Jedis 的 Api,和原生 Redis 命令命名上很接近,为了方便理解这里用 Jedis 实现。

   @Autowiredprivate Jedis jedis;private String RANKING_NAME = "ranking";private String LIVE_ROME = "liveRoom";private String ROOM_NAME = "李佳琦的直播间";@ApiOperation("热搜文章分页查询:zrevrangeWithScores 分页查询 0,-1 查全部")@PostMapping("rankingList")public Result rankingList() {return Result.success(jedis.zrevrangeWithScores(RANKING_NAME, 0, -1));}@ApiOperation("成员当前排名")@PostMapping("pos/{member}")public Result pos(@PathVariable("member") String member) {return Result.success((jedis.zrevrank(RANKING_NAME, member) + 1));}@ApiOperation("刷礼物(没有当前成员则新增、有则修改分数)")@PostMapping("weighting/{member}/{source}")public Result pos(@PathVariable("member") String member,@PathVariable("source") String source) {jedis.zincrby(RANKING_NAME, Double.parseDouble(source), member);return Result.success("ok");}

小结 ZSET

由于大家做的业务都不一样,本文只提供实现热点文章排行榜的基本思路。 举2个常见的排行榜开发业务如下

一种是纯 Redis 实现的在线排行榜: 同学 A 做的是直播聊天室业务,里面需要彰显榜一大哥实力,因此需要搞个在线的排行榜,并且还要实现刷礼物、在线人数新增记录、在线人数统计、排名这些需求,为了提升性能,完全就可以用Redis 做数据库。所有操作基于 Redis 完成,至于结果数据的持久化的话,只需在直播间关闭的时候,将数据落库到 Mysql 或者 Oracle 即可。之前写过一个聊天系统,在线人数统计就是每新开一个 Scoket 的时候,人数加 1,我就是这么干的。具体业务不多 bb。

还有一种是通过定时刷新实现的非实时排行榜 同学 b 的公司,不是查实时排行榜,而是通过定时刷数据库同步数据到 redis 中实现的。

小咸鱼的技术窝

关注不迷路,分享更多技术干货B站、CSDN、微信公众号同名(小咸鱼的技术窝),更多详情在主页
在这里插入图片描述

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

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

相关文章

Latex去掉参考文献后面的参考文献所在页(去掉参考文献的反向超链接)

如下&#xff1a; 在使用latex插入参考文献的时候&#xff0c;最后面总是会出现这种代号。这是表明的是这条参考文献所在的页码&#xff0c;并且点击之后可以跳转到该页。正式来讲&#xff0c;这个叫超链接的BACKREF。若要去掉&#xff0c;只需要在引用hyperref的时候去掉page…

技术or管理?浅谈软件测试人员的未来职业发展,值得借鉴

我们在工作了一段时间之后&#xff0c;势必会感觉到自己已经积累了一些工作经验了&#xff0c;会开始考虑下一阶段的职业生涯会如何发展。测试人员在职业生涯中的不确定因素还是不少的&#xff0c;由于其入门门槛不高&#xff0c;不用学习太多技术性知识即可入行&#xff0c;所…

Net8 EFCore Mysql 连接

一、安装插件 Pomelo.EntityFrameworkCore.MySq (这里要选8.0.0以上版本低版本不支持.net8) 二、配置数据库连接串 appsettings.json 中配置数据库连接串 "ConnectionStrings": {"Connection": "server172.18.2.183;port3306;databasestudents;uid…

使用opencv将8位图像raw数据转成bmp文件的方法

作者&#xff1a;朱金灿 来源&#xff1a;clever101的专栏 为什么大多数人学不会人工智能编程&#xff1f;>>> 这里说的图像raw数据是只包含图像数据的缓存。主要使用了cv::imencode接口将 cv::Mat转化为图像缓存。 #include <opencv2/opencv.hpp>/* 生成一幅…

【若依框架实现上传文件组件】

若依框架中只有个人中心有上传图片组件&#xff0c;但是这个组件不适用于el-dialog中的el-form表单页面 于是通过elementui重新写了一个上传组件&#xff0c;如图是实现效果 vue代码 <el-dialog :title"title" v-model"find" width"600px"…

Pytorch进阶教学——训练一个图像分类模型(GPU)

目录 1、前言 2、数据集介绍 3、获取数据 4、创建网络 5、训练模型 6、测试模型 6.1、测试整个模型准确率 6.2、测试单张图片 1、前言 编写一个可以分类蚂蚁和蜜蜂图片的模型&#xff0c;使用数据集对卷积神经网络进行训练。训练后的模型可以对蚂蚁或蜜蜂的图片进行…

【广州华锐互动】VR沉浸式体验铝厂安全事故让伤害教育更加深刻

随着科技的不断发展&#xff0c;虚拟现实&#xff08;VR&#xff09;技术已经逐渐渗透到各个领域&#xff0c;为我们的生活带来了前所未有的便捷和体验。在安全生产领域&#xff0c;VR技术的应用也日益受到重视。 VR公司广州华锐互动就开发了多款VR安全事故体验系统&#xff0c…

蓝桥杯-03-蓝桥杯学习计划

蓝桥杯-03-蓝桥杯学习计划 参考资料 相关文献 报了蓝桥杯比赛&#xff0c;几乎零基础&#xff0c;如何准备&#xff0c;请大牛指导一下。谢谢&#xff1f; 蓝桥杯2022各组真题汇总(完整可评测) 基础学习 C语言网 ACM竞赛入门,蓝桥杯竞赛指南 廖雪峰的官方官网 算法题单 洛谷…

vue,nvue,uniapp,到底是什么

vue,nvue,uniapp,到底是什么&#xff1f; 发展猜想&#xff1a; 开发移动端软件&#xff0c;一般是控件逻辑&#xff0c;可拖动控件android studio都给你设计好了。 开发web页面时&#xff0c;用vue&#xff0c;vue是前端框架。主要是终端设备通过浏览器进行访问&#xff08…

ubuntu20.04使用LIO-SAM对热室空间进行重建

一、安装LIO-SAM 1.环境配置 默认已经安装过ros sudo apt-get install -y ros-Noetic-navigation sudo apt-get install -y ros-Noetic-robot-localization sudo apt-get install -y ros-Noetic-robot-state-publisher 安装 gtsam(如果是18.04的ubuntu直接按照官网配置&…

C++ 基础篇

目录 C开发概述 C特点 C跨平台的原因 C编译器 C库 操作系统API C基本概念 注释 变量 常量 两种定义常量方式的区别 表示符命名规则 常见的关键字 数据类型 整型 浮点数 字符型 转义字符 字符串型 布尔类型 运算符 算术运算符 赋值运算符 比较运算符 逻…

【VScode】超详细图片讲解下载安装、环境配置、编译执行、调试

这里是目录 VScode是什么&#xff1f;VScode的下载和安装环境介绍安装中文插件 配置VScodeC/C开发环境下载和配置MinGW-w64 编译器套件下载&#xff1a;配置&#xff1a; 安装C/C插件在VScode上编写代码设置C/C编译选项创建执行任务编译执行如果想写其他代码在同一个文件夹在不…

springboot 整合 Spring Security 中篇(RBAC权限控制)

1.先了解RBAC 是什么 RBAC(Role-Based Access control) &#xff0c;也就是基于角色的权限分配解决方案 2.数据库读取用户信息和授权信息 1.上篇用户名好授权等信息都是从内存读取实际情况都是从数据库获取&#xff1b; 主要设计两个类 UserDetails和UserDetailsService 看下…

新媒体营销模拟实训室解决方案

一、引言 随着互联网的发展&#xff0c;新媒体已成为企业进行营销和品牌推广的重要渠道。然而&#xff0c;对于许多企业来说&#xff0c;如何在新媒体上进行有效的营销仍是一大挑战。为了解决这个问题&#xff0c;我们推出了一款新媒体营销模拟实训室解决方案&#xff0c;以帮…

【文末送书】Python OpenCV从入门到精通

文章目录 &#x1f354;简介opencv&#x1f339;内容简介&#x1f6f8;编辑推荐&#x1f384;导读&#x1f33a;彩蛋 &#x1f354;简介opencv OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉库&#xff0c;提供了丰富的图像处理和…

java学习part31String

142-常用类与基础API-String的理解与不可变性_哔哩哔哩_bilibili 1.String 2.字符串常量池 变更储存区的原因是加快被gc的频率 比地址&#xff0c;equals比内容 3.字符串连接 s3s4都是字符串常量&#xff0c;后面几个会利用StringBuilder的toString&#xff08;&#xff09;&a…

JAVA全栈开发 day16_MySql01

一、数据库 1.数据储存在哪里&#xff1f; 硬盘、网盘、U盘、光盘、内存&#xff08;临时存储&#xff09; 数据持久化 使用文件来进行存储&#xff0c;数据库也是一种文件&#xff0c;像excel &#xff0c;xml 这些都可以进行数据的存储&#xff0c;但大量数据操作&#x…

C#网络编程TCP程序设计(Socket类、TcpClient类和 TcpListener类)

目录 一、Socket类 1.Socket类的常用属性及说明 2.Socket类的常用方法及说明 二、TcpClient类 三、TcpListener类 四、示例 1.源码 2.生成效果 TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。在C#中&#xff0c;TCP程序设…

react-flip-move结合array-move实现前端列表置顶效果

你有没有遇到这样的需求&#xff1f;点击左侧列表项&#xff0c;则像聊天会话窗口一样将被点击的列表项置顶。 如果只是单纯的置顶的话&#xff0c;直接使用array-move就可以实现了&#xff0c;但置顶效果多少有点突兀~ 先上代码&#xff0c;直接使用array-move的情况&#xf…

数据可视化私有化部署:为何成本居高不下?

尽管在可视化设计这行干了好多年&#xff0c;也接手过不少项目&#xff0c;但昂贵的私有化部署费用总能让我发出由衷的感叹&#xff1a;“这几十万一年也太贵了&#xff01;”。可以预见&#xff0c;数据可视化软件私有化部署所带来的高昂成本&#xff0c;将是许多企业面临的问…