【Redis】List 列表
文章目录
- 初识列表
- 常用命令
- lpush
- lpushx
- lrange
- rpush
- rpushx
- lpop & rpop
- lindex
- linsert
- llen
- 阻塞操作 —— blpop & brpop
- 内部编码
- 应用场景
初识列表
列表类型,用于存储多个字符串。在操作和实现上,类似 C++ 的双端队列,支持随机访问(O(N)),头插头删尾插尾删(O(1)),详细可参看【C++】deque 双端队列
大致实现为,使用一个数组,其中每个元素都是一个数组指针。从数组中间开始插入元素,头插则从中间往前插入,尾插则从中间往后插入
Redis 实现的列表如下图,有相对顺序,规定左边为头,下标从0开始,如下图。每个元素从左到右构成一个有序的列表,此处的有序是有顺序,不是排序。列表的每个字符串称为元素
,允许有重复的值,一个列表最多存储 232 - 1 个元素。
功能上,支持从两端插入(push)和弹出(pop),还可以获取指定范围的元素列表,获取指定索引下标的元素,常被用于实现栈
或队列
常用命令
lpush
将一个或多个元素从左侧插入(头插)到 list 中。left push
lpush key element [element …]
返回值:完成插入操作后,list 的长度
示例:
127.0.0.1:6379> lpush list1 1 2 3 4
(integer) 4
lpushx
在 key 存在时才能将一个或多个元素从左侧插入(头插)到 list 中,不存在 key 则直接返回。left push exist
lpushx key element [element …]
返回值:完成插入操作后,list 的长度
示例:
127.0.0.1:6379> lpushx list1 6 7 8 9
(integer) 8
127.0.0.1:6379> lpushx list2 1234
(integer) 0
lrange
获取指定范围的 list 的元素,从 start 到 stop,左闭右闭
其中 start 和 stop 的值可正可负,负数则表示倒数,-1 表示倒数第一个数,-2 代表倒数第二个数,以此类推
PS:lrange 是 list range
,而不是 left range,而是 ,所以没有 rrange
lrange key start stop
返回值:指定区间的元素
备注:如果指定的区间不存在或无值,则返回空。若指定的区间有部分越界,并不会报错,而是把能返回的值返回
示例:
127.0.0.1:6379> lrange list2 0 -1
(empty array)
127.0.0.1:6379> lrange list1 0 -1
1) "9"
2) "8"
3) "7"
4) "6"
5) "4"
6) "3"
7) "2"
8) "1"
127.0.0.1:6379> lrange list1 100 300
(empty array)
127.0.0.1:6379> lrange list1 0 300
1) "9"
2) "8"
3) "7"
4) "6"
5) "4"
6) "3"
7) "2"
8) "1"
因为插入元素时使用的是 lpush 和 lpushx,会将元素从左往右依次插入
rpush
将一个或者多个元素从右侧插入(尾插),right push
rpushx key element [element …]
返回值:插入后 list 的长度
示例:
127.0.0.1:6379> rpush key2 1 2 3 4
(integer) 4
127.0.0.1:6379> lrange key2 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
rpushx
在 key 存在时才能将一个或多个元素从右侧插入(尾插)到 list 中,不存在 key 则直接返回。reft push exist
rpushx key element [element …]
返回值:完成插入操作后,list 的长度
示例:
127.0.0.1:6379> rpush key2 6 7 8 9
(integer) 8
127.0.0.1:6379> lrange key2 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
5) "6"
6) "7"
7) "8"
8) "9"
lpop & rpop
lpop
从 list 的左侧取出元素(头删),left pop
lpop key
返回值:取出的元素或者 nil
示例:
127.0.0.1:6379> lrange list1 0 -1
1) "9"
2) "8"
3) "7"
4) "6"
5) "4"
6) "3"
7) "2"
8) "1"
127.0.0.1:6379> lpop list1
"9"
127.0.0.1:6379> lpop list1
"8"
127.0.0.1:6379> lpop list1
"7"
127.0.0.1:6379> lpop list1
"6"
127.0.0.1:6379> lrange list1 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
rpop
从 list 右侧取出元素(尾删),right pop
rpop key
返回值:取出的元素或 nil
示例:
127.0.0.1:6379> lrange list1 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
127.0.0.1:6379> rpop list1
"1"
127.0.0.1:6379> rpop list1
"2"
127.0.0.1:6379> rpop list1
"3"
127.0.0.1:6379> rpop list1
"4"
127.0.0.1:6379> rpop list1
(nil)
127.0.0.1:6379> lrange list1 0 -1
(empty array)
lindex
获取从左往右数下标为 index 的元素,list index
index 支持正数或负数,负数则表示倒数第 index 个
lindex key index
返回值:取出的元素或者 nil
示例:
127.0.0.1:6379> lrange key2 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
5) "6"
6) "7"
7) "8"
8) "9"
127.0.0.1:6379> lindex key2 0
"1"
127.0.0.1:6379> lindex key2 1
"2"
127.0.0.1:6379> lindex key2 -1
"9"
127.0.0.1:6379> lindex key2 -2
"8"
linsert
在特定位置插入元素,list insert
linsert key <before | after> pivot element
返回值:插入后 list 的长度
备注:pivot 是列表中存在的数,可选择在其前插入或其后插入,若列表不存在该数,则返回 -1。如果列表存在多个 pivot,因为是从左往右遍历,只会找到第一个
示例:
127.0.0.1:6379> lrange key1 0 -1
1) "7"
2) "6"
3) "5"
4) "3"
5) "4"
6) "3"
7) "2"
8) "1"
127.0.0.1:6379> linsert key1 before 3 100
(integer) 9
127.0.0.1:6379> lrange key1 0 -1
1) "7"
2) "6"
3) "5"
4) "100"
5) "3"
6) "4"
7) "3"
8) "2"
9) "1"
127.0.0.1:6379> linsert key1 after 3 200
(integer) 10
127.0.0.1:6379> lrange key1 0 -11) "7"2) "6"3) "5"4) "100"5) "3"6) "200"7) "4"8) "3"9) "2"
10) "1"
127.0.0.1:6379> linsert key1 after 10 200
(integer) -1
llen
获取 list 的长度,list len
llen key
返回值:list 的长度
示例:
127.0.0.1:6379> lrange key1 0 -11) "7"2) "6"3) "5"4) "100"5) "3"6) "200"7) "4"8) "3"9) "2"
10) "1"
127.0.0.1:6379> llen key1
(integer) 10
阻塞操作 —— blpop & brpop
blpop
和 brpop
是 lpop 和 rpop 的阻塞版本,block left pop 和 block right pop
blpop key [key …] timeout
brpop key [key …] timeout
作用基本一致,但有以下区别:
- 在列表有元素的情况下,阻塞版本和非阻塞的表现是一致的,都直接取出元素并返回。但如果列表没有元素,非阻塞版本会直接返回 nil,而阻塞版本会根据
timeout
,阻塞一段时间,期间 Redis 服务端可以执行其他命令,但执行该命令的客户端会进行阻塞状态 - blpop 和 brpop 可以支持取出多个列表的元素,如果设置了多个列表,那么会从左往右依次尝试进行取出操作,一旦有一个列表不为空,可以弹出元素,则进行弹出操作并返回元素。
即并不是弹出多个列表的元素,而是从这些列表中弹出一个元素
- 如果多个客户端同时对同一个列表进行阻塞弹出操作,则最先执行命令的客户端会先尝试进行弹出操作,如果列表为空,则都阻塞,直到列表有元素,也是最先执行命令的客户端可以弹出元素
- timeout 单位为秒
示例:
127.0.0.1:6379> keys *
1) "key2"
2) "key1"
127.0.0.1:6379> lrange key1 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
127.0.0.1:6379> lrange key2 0 -1
1) "1"
2) "1"
3) "11"
127.0.0.1:6379> blpop key1 key2 10
1) "key1"
2) "4"
127.0.0.1:6379> blpop key3 key2 10
1) "key2"
2) "1"
内部编码
在旧版本时,列表的内部编码有两种:
- ziplist(压缩列表):当列表的元素个数小于
list-max-ziplist-entries
配置(默认 512 个),同时列表中每个元素的长度都小于list-max-ziplist-value
配置(默认 64 字节)时,Redis 会选用 ziplist 来作为列表的内部编码实现来减少内存消耗。 - linkedlist(链表):当列表类型无法满足 ziplist 的条件时,Redis 会使用 linkedlist 作为列表的内部实现。
在较新版本,列表的内部编码统一使用 quicklist
实现
127.0.0.1:6379> object encoding key1
"quicklist"
应用场景
模拟栈或队列
列表使用双端队列,两端的插入和删除很高效,而栈和队列都是操作受限的队列,双端队列非常适合实现,C++ 的 STL 也是如此,queue 和 stack 的底层都使用 deque(双端队列)实现
- 当只使用同一端操作时,即
lpush & lpop
或rpush & rpop
即可模拟栈 - 当只使用对端相反操作时,即
lpush & rpop
或rpush & lpop
即可模拟队列
消息队列
如下图所示
Redis 可使用 lpush + brpop
命令组合实现经典的阻塞式生产者 - 消费者模型队列,生产者客户端使用 lpush 从列表左侧插入元素,多个消费者客户端使用 brpop 命令,阻塞式地从队列中取出元素。通过多个客户端来保证消费的负载均衡和高可用性
分频道的消息队列
如图下图所示
Redis 同样使用 lpush + brpop
命令,但通过不同的键模拟频道的概念,不同的消费者可以通过 brpop 获取不同的键值,实现订阅不同频道的理念。
以上就是本篇博客的所有内容,感谢你的阅读
如果觉得本篇文章对你有所帮助的话,不妨点个赞支持一下博主,拜托啦,这对我真的很重要。
相关文章:

【Redis】List 列表
文章目录 初识列表常用命令lpushlpushxlrangerpushrpushxlpop & rpoplindexlinsertllen阻塞操作 —— blpop & brpop 内部编码应用场景 初识列表 列表类型,用于存储多个字符串。在操作和实现上,类似 C 的双端队列,支持随机访问(O(N)…...

JUC入门(四)
ReadWriteLock 代码示例: package com.yw.rw;import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.ReentrantReadWriteLock;public class ReadWriteDemo {public static void main(String[] args) {MyCache myCache new MyCache…...

【HarmonyOS 5】鸿蒙mPaaS详解
【HarmonyOS 5】鸿蒙mPaaS详解 一、mPaaS是什么? mPaaS 是 Mobile Platform as a Service 的缩写,即移动开发平台。 蚂蚁移动开发平台mPaaS ,融合了支付宝科技能力,可以为移动应用开发、测试、运营及运维提供云到端的一站式解决…...
多线BGP服务器优化实践与自动化运维方案
背景:企业级网络架构中的线路选择难题 在分布式业务部署场景下,如何通过三网融合BGP服务器实现低延迟、高可用访问?本文以某电商平台流量调度优化为案例,解析动态BGP服务器的实战价值。 技术方案设计 核心架构:采用…...

无法加载文件 E:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本
遇到“无法加载文件 E:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本”这类错误,通常是因为你的 PowerShell 执行策略设置为不允许运行脚本。在 Windows 系统中,默认情况下,出于安全考虑,PowerShell 可能会阻止运行未…...

【C++模板与泛型编程】实例化
目录 一、模板实例化的基本概念 1.1 什么是模板实例化? 1.2 实例化的触发条件 1.3 实例化的类型 二、隐式实例化 2.1 隐式实例化的工作原理 2.2 类模板的隐式实例化 2.3 隐式实例化的局限性 三、显式实例化 3.1 显式实例化声明(extern templat…...
TB开拓者策略交易信号闪烁根因及解决方法
TB开拓者策略信号闪烁分析 TB开拓者策略交易信号闪烁根因 TB开拓者策略交易信号闪烁根因分析 信号闪烁是交易策略开发中常见的问题,特别是在TB(TradeBlazer)开拓者等平台上。以下是信号闪烁的主要根因分析: 主要根因 未来函数问题 使用了包含未来信息…...

什么是RDMA?
什么是RDMA? RDMA(RemoteDirect Memory Access)技术全称远程直接内存访问,就是为了解决网络传输中服务器端数据处理的延迟而产生的。它将数据直接从一台计算机的内存传输到另一台计算机,无需双方操作系统的介入。这允许高吞吐、低延迟的网络…...
C++面试3——const关键字的核心概念、典型场景和易错陷阱
const关键字的核心概念、典型场景和易错陷阱 一、const本质:类型系统的守护者 1. 与#define的本质差异 维度#defineconst编译阶段预处理替换编译器类型检查作用域无作用域(全局污染)遵循块作用域调试可见性符号消失保留符号信息类型安全无类…...

ASIC和FPGA,到底应该选择哪个?
ASIC和FPGA各有优缺点。 ASIC针对特定需求,具有高性能、低功耗和低成本(在大规模量产时);但设计周期长、成本高、风险大。FPGA则适合快速原型验证和中小批量应用,开发周期短,灵活性高,适合初创企…...
【C++】嵌套类访问外部类成员
文章目录 C嵌套类访问外部类成员详解:权限、机制与最佳实践一、默认访问权限:并非友元二、访问外部类私有成员的方法1. 声明友元关系2. 通过公有接口访问 三、静态成员 vs. 非静态成员四、实际应用案例:Boost.Asio线程池场景需求实现关键代码…...
mac下载、使用mysql
1.如果对版本没有特别要求,那么直接使用brew install mysql安装即可。 2.使用 brew services start mysql 启动mysql。 3.使用 mysql -u root 登录mysql,这个时候还是不需要密码的 4.退出数据库:exit 5.给root设置一个密码,使用 m…...
java Lombok 对象模版和日志注解
目录 1、依赖: 2、在Idea中确认是否安装Lombok 插件 3、 Lombok常用注解 3.1 Getter 和 Setter 3.2 ToString 3.3 AllArgsConstructor 和 NoArgsConstructor 3.4 Data 3.5 FieldDefaults 4、 Slf4j 日志注解 4.2 日志级别 4.3 设置日志级别 1、依赖:…...

Python学习笔记--使用Django操作mysql
注意:本笔记基于python 3.12,不同版本命令会有些许差别!!! Django 模型 Django 对各种数据库提供了很好的支持,包括:PostgreSQL、MySQL、SQLite、Oracle。 Django 为这些数据库提供了统一的调…...
win11下,启动springboot时,提示端口被占用的处理方式
注:此操作可能存在风险!! 在启动springboot时,提示端口被占用。于是执行 #查看所有的占用的端口 netstat -ano | findStr 8080 结果发现并没有什么进程占据8080端口。再次执行: # 查看系统保留端口 netsh int ipv4…...

计算机视觉设计开发工程师学习路线
以下是一条系统化的计算机视觉(CV)学习路线,从基础到进阶,涵盖理论、工具和实践,适合逐步深入,有需要者记得点赞收藏哦: 相关学习:python深度学习,python代码定制 python…...
AI大模型从0到1记录学习numpy pandas day25
第 3 章 Pandas 3.1 什么是Pandas Pandas 是一个开源的数据分析和数据处理库,它是基于 Python 编程语言的。 Pandas 提供了易于使用的数据结构和数据分析工具,特别适用于处理结构化数据,如表格型数据(类似于Excel表格)…...
Opencv C++写中文(来自Gemini)
基于与Google Gemini交互获取的Opencv在图片上写汉字的实现 sudo apt-get install libfreetype6-dev sudo apt-get install fonts-wqy-zenhei CMakeLists.txt cmake_minimum_required(VERSION 3.10) # Or a more recent versionproject(OpenCVChineseText)set(CMAKE_CXX_STAN…...
下载和导出文件名称乱码问题
只对文件名称进行乱码处理,和文件中的内容无关。 import lombok.SneakyThrows; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.cont…...

STM32实战指南:DHT11温湿度传感器驱动开发与避坑指南
知识点1【DHT11的概述】 1、概述 DHT是一款温湿度一体化的数字传感器(无需AD转换)。 2、驱动方式 通过单片机等微处理器简单的电路连接就能实时采集本地湿度和温度。DHT11与单片机之间采用单总线进行通信,仅需要一个IO口。 相对于单片机…...

【android bluetooth 协议分析 01】【HCI 层介绍 8】【ReadLocalVersionInformation命令介绍】
1. HCI_Read_Local_Version_Information 命令介绍 1. 功能(Description) HCI_Read_Local_Version_Information 命令用于读取本地 Bluetooth Controller 的版本信息,包括 HCI 和 LMP 层的版本,以及厂商 ID 和子版本号。 这类信息用…...

esp32课设记录(四)摩斯密码的实现 并用mqtt上传
摩斯密码(Morse Code)是一种通过点(.)和划(-)组合来表示字符的编码系统。下面我将在esp32上实现摩斯密码的输入,并能够发送到mqtt的broker。 先捋一下逻辑,首先esp32的按键已经编写了短按与长按功能,这将是输出摩斯密码点和划的基础。然后当2…...

「HHT(希尔伯特黄变换)——ECG信号处理-第十三课」2025年5月19日
一、引言 心电信号(ECG)是反映心脏电活动的重要生理信号,其特征提取对于心脏疾病的诊断和监测具有关键意义。Hilbert - Huang Transform(HHT)作为一种强大的信号处理工具,在心电信号特征提取领域得到了广泛…...

前端(vue)学习笔记(CLASS 6):路由进阶
1、路由的封装抽离 将之前写在main.js文件中的路由配置与规则抽离出来,放置在router/index.js文件中,再将其导入回main.js文件中,即可实现路由的封装抽离 例如 //index.js import { createMemoryHistory, createRouter } from vue-routerim…...

GPT-4.1特点?如何使用GPT-4.1模型,GPT-4.1编码和图像理解能力实例展示
几天前,OpenAI在 API 中推出了三个新模型:GPT-4.1、GPT-4.1 mini 和 GPT-4.1 nano。这些模型的性能全面超越 GPT-4o 和 GPT-4o mini(感觉这个GPT-4.1就是GPT-4o的升级迭代版本),主要在编码和指令跟踪方面均有显著提升。还拥有更大的上下文窗口…...
使用Python和FastAPI构建网站爬虫:Oncolo医疗文章抓取实战
使用Python和FastAPI构建网站爬虫:Oncolo医疗文章抓取实战 前言项目概述技术栈代码分析1. 导入必要的库2. 初始化FastAPI应用3. 定义请求模型4. 核心爬虫功能4.1 URL验证和准备4.2 设置HTTP请求4.3 发送请求和解析HTML4.4 提取文章内容4.5 保存结果和返回数据 5. AP…...
写一段图片平移的脚本
问题描述: 写一段图片平移的脚本。 平移就是将对象换一个位置。如果你要沿方向移动,移动的距离是,你可以以下面的方式构建移动矩阵:。 你可以使用Numpy 数组构建这个矩阵(数据类型是np.float32)…...

【C++】哈希的概念与实现
1.哈希概念 通过某种函数使元素的存储位置与它的关键码之间能够建立一一映射的关系,可以不经过任何比较,一次直接从表中得到要搜索的元素。 当向该结构中: 插入元素: 根据待插入元素的关键码,以此函数计算出该元素的…...

Yocto和Buildroot功能和区别
一.介绍 Yocto 和 Buildroot 都是用于嵌入式 Linux 系统开发的工具集,它们的目的是帮助开发者轻松构建定制的 Linux 系统镜像,以便在嵌入式设备上运行。 二.对比 1.Yocto Yocto 是一个开源的嵌入式 Linux 构建系统,它允许开发者创建自定义…...
物联网数据湖架构
物联网海量数据湖分析架构(推荐实践) ┌──────────────┐ │ IoT设备端 │ └──────┬───────┘│(MQTT/HTTP)▼ ┌──────────────┐ │ EMQX等 │ 可选(也可…...