图解Redis 03 | List数据类型的原理及应用场景

介绍

List是一个简单的字符串列表,按照元素的插入顺序进行排序。您可以从头部或尾部添加元素到这个列表中。

列表的最大长度为2^32 - 1,即支持多达40亿个元素。

内部实现

List 类型的底层数据结构在 Redis 中可以采用双向链表或压缩列表(ziplist),具体使用哪种结构取决于列表的元素数量和每个元素的大小:

  • 如果List中的元素数量少于 512 个(默认值,可通过配置 list-max-ziplist-entries 调整),且每个元素的值小于 64 字节(默认值,可通过配置 list-max-ziplist-value 调整),Redis 会使用压缩列表作为底层数据结构。这种结构有助于节省内存。

  • 如果List的元素数量超过上述限制或单个元素的大小超过了规定的字节数,Redis 会改用双向链表作为底层数据结构,以支持更复杂的操作。

不过从 Redis 3.2 版本开始,List 数据类型的底层数据结构被统一为 quicklist,这种结构结合了压缩列表和双向链表的优点,取代了原有的双向链表和压缩列表。

常用命令

以下是Redis List类型的一些常用命令:

#将一个或多个值从List左边插入。
LPUSH key value [value...]#将一个或多个值从List右边插入。
RPUSH key value [value...]#删除并返回List左边的元素。
LPOP key#删除并返回List右边的元素。
RPOP key# 获取List中元素的个数。
LLEN key#获取List指定范围内的元素。
LRANGE key start stop#按指定数量移除List中的元素
LREM key count value#设置List中指定索引处的元素。
LSET key index value#修剪List
LTRIM key start stop:

示例:

> lpush mq 10001:stock:9
(integer) 1
> lpush list v1
(integer) 1
> rpush list v2
(integer) 2
> rpush list v3
(integer) 3
> llen list
(integer) 3
> lrange list 0 2
1) "v1"
2) "v2"
3) "v3"
> lpop list
"v1"
> llen list
(integer) 2

应用场景

1. 消息队列

消息队列在处理和存储消息时,必须满足以下三个要求:

  • 保证消息顺序
  • 处理重复消息
  • 确保消息的可靠性。

Redis 的两种数据类型——List 和 Stream都可以用来实现消息队列的功能。

首先,我们将探讨如何使用 List 实现消息队列的功能,后面在介绍 Stream 数据类型时,我们将详细讨论 Stream 的实现方式。

1. 如何满足消息有序性

List本身是按照先进先出的顺序访问和存储数据的,所以如果使用List作为消息队列来保存消息,已经可以满足消息有序性的要求了。

List可以使用LPUSH+RPOP(或反之,RPUSH+LPOP)命令实现消息队列。

  1. 生产者:使用命令LPUSH key value[value…]将消息插入到List头部,如果key不存在,则会创建一个空List然后插入消息。
  2. 消费者:使用命令RPOP key按顺序读取List的消息,先进先出。

然而,这种方法存在一个问题:当生产者往 List 中写入数据时,Redis 不会主动通知消费者有新数据到达。

为了让消费者能够及时处理消息,通常需要在程序中不断调用 RPOP 命令,比如通过 while(1) 循环来轮询队列。如果队列中有新数据,RPOP 命令会返回该消息;如果队列为空,RPOP 命令将返回空值,消费者则会继续循环等待新的数据。

因此,即使没有新的消息写入 List,消费者也需要不断调用 RPOP 命令,这会导致消费者程序的 CPU 不断消耗在执行 RPOP 命令上,带来不必要的性能损失。

为了解决这个问题,Redis 提供了 BRPOP 命令。BRPOP 命令是一个阻塞读取命令,当客户端没有读取到队列数据时,BRPOP 会自动阻塞,直到有新数据写入队列后才会继续执行。与消费者程序自己不断调用 RPOP 命令不同,BRPOP 能有效节省 CPU 开销,因为它只在有新数据时才会返回结果。

2. 如何处理重复消息?

消费者要实现重复消息的判断,需要满足两个要求:

  • 每条消息都应具有一个全局唯一的 ID。
  • 消费者需要记录已经处理过的消息 ID。在收到一条新消息后,消费者程序可以通过比较消息的 ID 与已记录的 ID 来判断消息是否已经处理过,如果消息已处理过,则跳过处理。

List 本身并不为每条消息生成 ID,因此我们需要手动为每条消息生成一个全局唯一的 ID。在生成 ID 后,当我们使用 LPUSH 命令将消息插入 List 时,消息内容中需要包含这个唯一的 ID。

例如,我们可以执行以下命令,将一条全局唯一 ID 为 10001、库存数量为 9 的消息插入到消息队列中:

> LPUSH mq "10001:stock:9"
(integer) 1
3. 如何保证消息的可靠性?

当消费者程序从 List 中读取一条消息后,该消息将从 List 中移除。如果消费者在处理这条消息时发生故障或崩溃,那么这条消息就会丢失,消费者在重启后将无法再次从 List 中读取到这条消息。

为了解决这个问题,List 类型提供了 BRPOPLPUSH 命令。这个命令允许消费者程序从一个 List 中读取一条消息,同时将这条消息插入到另一个 List(可以称为备份 List)中进行保留。这样,如果消费者在处理消息时出现问题,消息将保留在备份 List 中。在消费者程序重启后,可以从备份 List 中重新读取并处理这些消息。

通过这种方式,基于 List 类型的消息队列能够满足三大需求:消息有序、处理重复消息和保证消息的可靠性。

  • 消息有序:使用 LPUSH + RPOP。
  • 阻塞读:使用 BRPOP。
  • 重复消息处理:生产者自行实现全局唯一 ID。
  • 消息可靠性:使用 BRPOPLPUSH。

List作为消息队列有什么缺陷?

不支持多个消费者消费同一条消息:一旦一个消费者拉取了某条消息,这条消息就会从 List 中删除,其他消费者将无法再读取这条消息。

为了解决这一问题,Redis 从 5.0 版本开始引入了 Stream 数据类型。Stream 不仅可以满足消息队列的三大需求,还支持以“消费者组”的形式读取消息。有关 Stream 数据类型的更多信息,我们将在后续的文章中详细介绍。

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

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

相关文章

vue3之插件

插件plugins是一种能为vue添加全局功能的代码,官网连接:https://cn.vuejs.org/guide/reusability/plugins.html 项目的src文件夹下新建plugins文件夹 新建i18n.js文件 插件是一个拥有install方法的对象 export default {install: (app, options)>{app.config.…

基于SSM+Vue+MySQL的少儿编程网上报名系统

系统展示 用户前台界面 管理员后台界面 系统背景 在当下,随着国家对教育的重视以及教育部门对教育改革的不断推进,少儿编程教育逐渐成为了一个热门领域。传统的少儿编程报名方式往往依赖于线下填写纸质表格或电话报名,这种方式不仅效率低下&a…

开发日志:IIS安全配置

为了解决IIS文件路径泄漏问题,可以采取以下措施: 一. 详细操作 1. CMD关闭NTFS 8.3文件格式的支持 命令行:fsutil 8dot3name set 1 2. 修改注册表禁用短文件名功能 CMD输入regedit回车,在注册表中找到HKEY_LOCAL_MACHINE\SYSTEM\C…

PHP政务招商系统——高效连接共筑发展蓝图

政务招商系统——高效连接,共筑发展蓝图 🏛️ 一、政务招商系统:开启智慧招商新篇章 在当今经济全球化的背景下,政务招商成为了推动地方经济发展的重要引擎。而政务招商系统的出现,更是为这一进程注入了新的活力。它…

【Java】I/O 操作详解

📃个人主页:island1314 ⛺️ 欢迎关注:👍点赞 👂🏽留言 😍收藏 💞 💞 💞 目录 1. 引言 🚀 2. File 类 📕 2.1 创建 File 对象 …

Golang | Leetcode Golang题解之第472题连接词

题目: 题解: type trie struct {children [26]*trieisEnd bool }func (root *trie) insert(word string) {node : rootfor _, ch : range word {ch - aif node.children[ch] nil {node.children[ch] &trie{}}node node.children[ch]}node.isE…

Qt-系统网络TCP回显客户端与服务端(65)

目录 描述 函数 使用 服务器 准备工作 声明相关函数与对象 绑定并监听 定义槽函数与连接 瑕疵 释放 客户端 准备工作 声明相关函数与对象 初始化并连接服务器 给发送添加槽函数 连接信号槽处理响应函数 测试运行 补充 代码 客户端 服务器 描述 有UDP&…

MySQL 删除数据库

1.使用命令行删除一个数据库 1.1 首先登陆进入 MySQL 操作界面,命令如下: 命令 : mysql -utest -p;1.2 登陆成功之后可以使用如下命令查看当前已有数据库: 命令 : SHOW DATABASES; 执行结果如下图: 如图所示当前已包含 MySQL 系统数据库和…

TensorRT-LLM七日谈 Day3

今天主要是结合理论进一步熟悉TensorRT-LLM的内容 从下面的分享可以看出,TensorRT-LLM是在TensorRT的基础上进行了进一步封装,提供拼batch,量化等推理加速实现方式。 下面的图片更好的展示了TensorRT-LLM的流程,包含权重转换&…

iPhone 16 Pro 拆解揭秘:设计改进与维修便利性

苹果最新推出的iPhone 16系列在许多方面都进行了更新和改进,而这次我们要聚焦的是其中的高端型号——iPhone 16 Pro。 这款手机不仅在性能上有所提升,在内部构造上也带来了不少变化,让我们一起来看看这些细节吧。 更容易进入的内部结构 对于…

一、Java基础

韩顺平Java基础 浮点型使用细节基本数据类型转换自动类型转换强制类型转换 浮点型使用细节 double d 8.1 / 3 的结果是一个非常接近2.7的小数,比如2.69999997,这是计算机的运算规则造成的 基本数据类型转换 自动类型转换 对于第四点,如下…

电脑知识:适用于 Windows 10 的 PDF 编辑器列表

PDF 是一种流行的、多功能且安全的文件格式,用于在线共享文档。但是,如果没有合适的应用程序,查看和编辑 PDF 文件可能会变得复杂。 幸运的是,有很多 PDF 编辑器可以帮助您更正重要文档上的错误、填写表格、为合同添加签名、更改…

Unity3d折叠Inspector中的变量

InspectorFoldoutGroup插件 [Pixeye.Unity.Foldout("【曲线图】")] public BrokenLineUpDownGraph aimStabilityGraph;[Pixeye.Unity.Foldout("【曲线图】")] public BrokenLineUpGraph aimDensityGraph;[Pixeye.Unity.Foldout("【曲线图】")] p…

MedMamba代码解释及用于糖尿病视网膜病变分类

MedMamba原理和用于糖尿病视网膜病变检测尝试 1.MedMamba原理 MedMamba发表于2024.9.28,是构建在Vision Mamba基础之上,融合了卷积神经网的架构,结构如下图: 原理简述就是图片输入后按通道输入后切分为两部分,一部分走…

Spring Boot 应用开发:入门与实战

Spring Boot 应用开发:入门与实战 引言 Spring Boot 是 Spring 框架的一个子项目,旨在简化 Spring 应用的配置和开发。它通过自动配置和嵌入式服务器,极大地简化了 Java 企业级应用的开发。本文将详细介绍 Spring Boot 的核心概念&#xff…

JVM进阶调优系列(1)类加载器原理一文讲透

今天开始写JVM调优系列,并发编程系列也会继续穿插连载,让各位同学闲暇之余有更多阅读选择。 起笔写第一篇,并不好写。首先要构思整个系列的大概框架,一个好的框架一定是深度上由浅入深、逻辑上有严格顺序,读者订阅跟踪…

《OpenCV计算机视觉》—— 人脸检测

文章目录 一、人脸检测流程介绍二、用于人脸检测的关键方法1.加载分类器(cv2.CascadeClassifier())2.检测图像中的人脸(cv2.CascadeClassifier.detectMultiscale()) 三、代码实现 一、人脸检测流程介绍 下面是一张含有多个人脸的…

使用camunda的DMN实现班级决策案例

班级决策 Camunda 支持DMN1.3版本,在BPMN业务活动流程中,可通过业务规则任务调用DMN决策。DMN决策目的是想把业务代码和决策进行解耦,使决策分析人员只需关心决策即可。 需求描述 通过幼儿园学生年龄age和身高height分配不同的班级&#xff0…

10.13论文阅读

通过联合学习检测和描述关键点增强可变形局部特征 摘要 局部特征提取是计算机视觉中处理图像匹配和检索等关键任务的常用方法。大多数方法的核心理念是图像经历仿射变换,忽略了诸如非刚性形变等更复杂的效果。此外,针对非刚性对应的新兴工作仍然依赖于…

个性化图像生成新王炸!无需微调,Meta重磅发布Imagine yourself:三大核心全面SOTA!

论文链接:https://arxiv.org/pdf/2409.13346 亮点直击 本文提出了“Imagine Yourself”,这是一种用于个性化图像生成的创新型最先进模型。该模型可以将任意参考图像作为输入进行定制化图像生成,并且不需要针对每个对象进行调整。“Imagine Yo…