Redis中的zset用法详解

news/2024/11/24 9:20:12/

文章目录

  • Redis中的zset用法详解
    • 一、引言
    • 二、zset的基本概念和操作
      • 1、zset的添加和删除
        • 1.1、添加元素
        • 1.2、删除元素
      • 2、zset的查询
        • 2.1、获取元素分数
        • 2.2、获取元素排名
      • 3、zset的范围查询
        • 3.1、按排名查询
        • 3.2、按分数查询
    • 三、zset的应用场景
      • 1、排行榜
        • 1.1、添加玩家得分
        • 1.2、获取排行榜
      • 2、延时队列
        • 2.1、添加任务
        • 2.2、处理到期任务
      • 3、滑动窗口限流
        • 3.1、记录请求
        • 3.2、检查请求频率
        • 3.3、清理旧请求
    • 四、总结

Redis中的zset用法详解

一、引言

Redis是一个开源的高性能键值对数据库,它支持多种类型的数据结构,其中之一就是有序集合(zset)。有序集合类似于集合(set),但它为每个元素关联了一个分数(score),使得元素可以按照分数进行排序。这种数据结构在实现排行榜、延时队列等场景中非常有用。

二、zset的基本概念和操作

1、zset的添加和删除

1.1、添加元素

向zset中添加元素可以使用ZADD命令。这个命令允许你将一个或多个元素及其分数添加到有序集合中。

ZADD myzset 1 "one" 2 "two" 3 "three"

上述命令将元素"one"、"two"和"three"及其对应的分数添加到名为myzset的有序集合中。

1.2、删除元素

从zset中删除元素可以使用ZREM命令。

ZREM myzset "two"

上述命令将元素"two"从myzset有序集合中删除。

2、zset的查询

2.1、获取元素分数

可以使用ZSCORE命令获取有序集合中元素的分数。

ZSCORE myzset "one"

上述命令将返回元素"one"的分数。

2.2、获取元素排名

可以使用ZRANKZREVRANK命令获取元素的排名,其中ZRANK返回升序排名,而ZREVRANK返回降序排名。

ZRANK myzset "two"
ZREVRANK myzset "two"

上述命令分别返回"two"的升序和降序排名。

3、zset的范围查询

3.1、按排名查询

可以使用ZRANGEZREVRANGE命令按排名查询元素。

ZRANGE myzset 0 -1 WITHSCORES
ZREVRANGE myzset 0 -1 WITHSCORES

上述命令分别返回myzset中所有元素及其分数,按照升序和降序排列。

3.2、按分数查询

可以使用ZRANGEBYSCORE命令按分数查询元素。

ZRANGEBYSCORE myzset 1 3

上述命令返回myzset中分数在1到3之间的所有元素。

三、zset的应用场景

1、排行榜

假设我们正在开发一个在线游戏,需要实现一个玩家得分排行榜。以下是如何使用Redis的zset来实现这个功能的具体步骤和代码示例。

1.1、添加玩家得分

当玩家完成游戏并获得分数时,我们将他们的得分和用户名添加到zset中。

ZADD game_scores 1000 user1 2000 user2 1500 user3

这里,game_scores是zset的名称,100020001500是玩家的得分,user1user2user3是对应的用户名。

1.2、获取排行榜

要获取排名前三的玩家,我们可以使用ZREVRANGE命令。

ZREVRANGE game_scores 0 2 WITHSCORES

这个命令将返回得分最高的三个玩家及其得分。

2、延时队列

假设我们需要实现一个任务队列,其中任务需要在特定时间后执行。以下是如何使用zset来实现延时队列的具体步骤和代码示例。

2.1、添加任务

当添加一个需要在未来执行的任务时,我们将任务的执行时间和任务ID作为元素和分数添加到zset中。

ZADD delayed_tasks <未来时间戳> task1 <另一个未来时间戳> task2

这里,<未来时间戳>是任务应该执行的时间(以时间戳表示),task1task2是任务的唯一标识符。

2.2、处理到期任务

定期运行一个脚本来检查是否有任务到期,并执行它们。

ZRANGEBYSCORE delayed_tasks 0 <当前时间戳>

这个命令将返回所有到期的任务(分数小于或等于当前时间戳的任务)。然后,你可以遍历这些任务并执行它们,最后从zset中删除这些任务。

ZREM delayed_tasks task1 task2

3、滑动窗口限流

假设我们需要对一个API接口进行限流,以确保在一分钟内不超过100次请求。以下是如何使用zset来实现滑动窗口限流的具体步骤和代码示例。

3.1、记录请求

每次API被调用时,我们将当前时间戳和请求标识符添加到zset中。

ZADD api_limit:<接口名称> <当前时间戳> <请求标识符>

这里,api_limit:<接口名称>是zset的名称,<当前时间戳>是请求发生的时间,<请求标识符>是每个请求的唯一标识符。

3.2、检查请求频率

在处理请求之前,检查过去一分钟内是否有超过100次请求。

ZCOUNT api_limit:<接口名称> <当前时间戳-60000> <当前时间戳>

这个命令将返回过去一分钟内(60000毫秒)的请求数量。如果这个数量超过了100,那么拒绝当前请求。

3.3、清理旧请求

为了保持zset的大小,定期删除超过时间窗口的请求。

ZREMRANGEBYSCORE api_limit:<接口名称> 0 <当前时间戳-60000>

这个命令将删除所有超过一分钟的请求记录。

以上示例展示了如何使用Redis的zset来实现排行榜、延时队列和滑动窗口限流功能。这些应用场景展示了zset的灵活性和强大的功能。

四、总结

Redis的zset是一个功能强大的有序集合数据结构,它不仅支持元素的添加、删除和查询,还支持范围查询和排名查询,非常适合实现排行榜、延时队列和限流等场景。通过合理使用zset,可以有效地解决许多实际问题。


版权声明:本博客内容为原创,转载请保留原文链接及作者信息。

参考文章

  • 零基础手把手带你阅读Redis源代码系列-ZSet底层原理详解(跳表SkipList)-阿里云开发者社区
  • redis 中Zset(有序集合)介绍 及常用命令(附有示例)_redis zset-CSDN博客

http://www.ppmy.cn/news/1549499.html

相关文章

简述C++map容器

pair键值对 std::pair在很多关联容器&#xff08;如std::map、std::multimap、std::set、std&#xff1a;multiset等&#xff09;中被广泛应用。以std::map为例&#xff0c;std::map是一个键值对的容器&#xff0c;其中每个元素都是一个std::pair&#xff0c;键用于唯一标识元…

【Linux网络 (二)】套接字编程

Linux: 网络 一、前言二、端口号 (port)1&#xff09;port、套接字概念2&#xff09;端口号 vs 进程id3&#xff09;端口号和进程关系 三、认识TCP/Udp协议1&#xff09;连接性解释2&#xff09;可靠性解释3&#xff09;面向数据报/字节流解释 四、网络字节序五、struct sockad…

【Isaac Sim】配置 Nucleus 本地服务器

Omniverse 提供了本地&#xff08;局域&#xff09;服务器 Nucleus&#xff0c;可以将资产上传到该服务器&#xff0c;Nucleus 能够高效地存储和管理大量三维模型和其他资产&#xff0c;确保用户可以轻松访问这些资源。它还支持多用户环境下的实时协作&#xff0c;使得不同地理…

【贪心算法】绿洲之旅:最少次数补给探索

文章目录 问题背景解决思路贪心算法的优势实现步骤详解 问题背景 假设一位旅行者需要穿越一片沙漠&#xff0c;起点到终点的距离为 D 公里&#xff0c;旅行者初始携带了 W 升水&#xff0c;每前进一公里需要消耗一升水。在穿越过程中&#xff0c;沿途会经过 N 个补给站&#x…

人工智能(AI)与机器学习(ML)基础知识

目录 1. 人工智能与机器学习的核心概念 什么是人工智能&#xff08;AI&#xff09;&#xff1f; 什么是机器学习&#xff08;ML&#xff09;&#xff1f; 什么是深度学习&#xff08;DL&#xff09;&#xff1f; 2. 机器学习的三大类型 &#xff08;1&#xff09;监督式学…

uiautomator案例

test下新建类 public class ButtonClickTest {private UiDevice device;Beforepublic void setUp() {// 初始化 UiDevice 实例device UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());try {device.executeShellCommand("am start -n com.yy.test/.…

JAVA部署到生产环境(服务器 全)

将Java应用部署到生产环境是一个复杂且需要细心规划的过程&#xff0c;主要包括代码准备、构建、测试、部署和监控等步骤。以下是一个完整的流程&#xff1a; 1. 准备阶段 1.1 确认需求与目标 确认生产环境的部署目标&#xff0c;例如性能要求、可用性、容灾能力等。制定部署…

leetcode刷题记录(四十二)——101. 对称二叉树

&#xff08;一&#xff09;问题描述 . - 力扣&#xff08;LeetCode&#xff09;. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/symmetric-tree/description/给你…