【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

blpopbrpop 是 lpop 和 rpop 的阻塞版本,block left pop 和 block right pop

blpop key [key …] timeout
brpop key [key …] timeout

作用基本一致,但有以下区别:

  1. 在列表有元素的情况下,阻塞版本和非阻塞的表现是一致的,都直接取出元素并返回。但如果列表没有元素,非阻塞版本会直接返回 nil,而阻塞版本会根据 timeout,阻塞一段时间,期间 Redis 服务端可以执行其他命令,但执行该命令的客户端会进行阻塞状态
  2. blpop 和 brpop 可以支持取出多个列表的元素,如果设置了多个列表,那么会从左往右依次尝试进行取出操作,一旦有一个列表不为空,可以弹出元素,则进行弹出操作并返回元素。即并不是弹出多个列表的元素,而是从这些列表中弹出一个元素
  3. 如果多个客户端同时对同一个列表进行阻塞弹出操作,则最先执行命令的客户端会先尝试进行弹出操作,如果列表为空,则都阻塞,直到列表有元素,也是最先执行命令的客户端可以弹出元素
  4. 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 & lpoprpush & rpop 即可模拟栈
  • 当只使用对端相反操作时,即 lpush & rpoprpush & lpop 即可模拟队列

消息队列

如下图所示

在这里插入图片描述

Redis 可使用 lpush + brpop 命令组合实现经典的阻塞式生产者 - 消费者模型队列,生产者客户端使用 lpush 从列表左侧插入元素,多个消费者客户端使用 brpop 命令,阻塞式地从队列中取出元素。通过多个客户端来保证消费的负载均衡和高可用性


分频道的消息队列

如图下图所示

在这里插入图片描述

Redis 同样使用 lpush + brpop 命令,但通过不同的键模拟频道的概念,不同的消费者可以通过 brpop 获取不同的键值,实现订阅不同频道的理念。


以上就是本篇博客的所有内容,感谢你的阅读
如果觉得本篇文章对你有所帮助的话,不妨点个赞支持一下博主,拜托啦,这对我真的很重要。
在这里插入图片描述

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

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

相关文章

Android framework 中间件开发(三)

前两篇我们讲了中间件的开发和打包应用, Android framework 中间件开发(一) Android framework 中间件开发(二) 这边我们来讲一下在中间件中编写JNI 1.新建C文件 找到frameworks\base\services\core\jni\路径,新建一个cpp文件,文件名为com_android_server_DarkControlService.c…

深入了解linux系统—— 基础IO(上)

文件 在之前学习C语言文件操作时&#xff0c;我们了解过什么是文件&#xff0c;这里简单回顾一下&#xff1a; 文件存在磁盘中&#xff0c;文件有分为程序文件、数据文件&#xff1b;二进制文件和文本文件等。 详细描述见文章&#xff1a;文件操作——C语言 文件在磁盘里&a…

Flink CDC—实时数据集成框架

Flink CDC 是一个基于流的数据集成工具&#xff0c;旨在为用户提供一套功能更加全面的编程接口&#xff08;API&#xff09;&#xff0c;它基于数据库日志的 CDC&#xff08;变更数据捕获&#xff09;技术实现了统一的增量和全量数据读取。 该工具使得用户能够以 YAML 配置文件…

ES(ES2023/ES14)最新更新内容,及如何减少内耗

截至2023年10月,JavaScript(ECMAScript)的最新版本是 ES2023(ES14)。 ES2023 引入了许多新特性,如findLast、toSorted等,同时优化了性能。通过减少全局变量、避免内存泄漏、优化循环、减少DOM操作、使用Web Workers、懒加载、缓存、高效数据结构和代码压缩,可以显著降低…

常见的 Python 环境配置问题及解决方案

1. Python 环境配置的常见问题 初学者在配置 Python 环境时&#xff0c;可能会遇到以下几类问题&#xff1a; 1.1 不同版本的兼容性 Python 目前有两个主要版本系列&#xff1a;Python 2.x 和 Python 3.x。Python 2.x 已于 2020 年 1 月 1 日停止维护&#xff0c;因此强烈建…

day20-线性表(链表II)

一、调试器 1.1 gdb&#xff08;调试器&#xff09; 在程序指定位置停顿 1.1.1 一般调试 gcc直接编译生成的是发布版&#xff08;Release&#xff09; gcc -g //-g调式版本&#xff0c;&#xff08;体积大&#xff0c;内部有源码&#xff09;&#xff08;DeBug&#…

基于Spring Boot+Layui构建企业级电子招投标系统实战指南

一、引言&#xff1a;重塑招投标管理新范式 在数字经济浪潮下&#xff0c;传统招投标模式面临效率低、透明度不足、流程冗长等痛点。本文将以Spring Boot技术生态为核心&#xff0c;融合Mybatis持久层框架、Redis高性能缓存及Layui前端解决方案&#xff0c;构建一个覆盖招标代理…

uniapp -- uCharts 仪表盘刻度显示 0.9999999 这样的值问题处理。

文章目录 🍉问题🍉解决方案🍉问题 在仪表盘上,23.8变成了 23.799999999999997 🍉解决方案 formatter格式化问题 1:在 config-ucharts.js 或 config-echarts.js 配置对应的 formatter 方法 formatter: {yAxisDemo1: function (

git 对于已经追踪,但没有git add 的文件,撤回修改的方法

要撤销对已追踪文件的修改&#xff08;但尚未使用git add添加到暂存区&#xff09;&#xff0c;你可以使用以下几种方法&#xff1a; 1. 使用 git restore (Git 2.23.0及更高版本) 这是较新版本Git中推荐的方式&#xff1a; # 撤销单个文件的修改git restore <file># …

脚本语言Lua

本文来源 &#xff1a;腾讯元宝 Lua是一种轻量级、可嵌入的脚本语言&#xff0c;由巴西里约热内卢天主教大学的Roberto Ierusalimschy、Waldemar Celes和Luiz Henrique de Figueiredo于1993年开发。其设计目标是嵌入应用程序中&#xff0c;提供灵活的扩展和定制功能。 主要特性…

ThingsBoard使用Cassandra部署时性能优化

1、概述 当遇到ThingsBoard设备数量特别多的时候,并且传输数据遥测点量特别大的时候,我们需要调整一下参数来进行优化,使其性能达到最佳的进行快速写入。 注意:以下这些参数再系统部署的时候就需要规划好配置,不能安装好了再二次来进行配置。 2、Cassandra配置参数优化 …

Git Worktree 使用

新入职了一家公司&#xff0c;发现不同项目用的使用一个 git 仓库管理。不久之后我看到这篇文章。 Git 的设计部​​分是为了支持实验。一旦你确定你的工作被安全地跟踪&#xff0c;并且存在安全的状态&#xff0c;以便在出现严重错误时可以恢复&#xff0c;你就不会害怕尝试新…

维智定位 Android 定位 SDK

概述 维智 Android 定位 SDK是为 Android 移动端应用提供的一套简单易用的定位服务接口&#xff0c;为广大开发者提供融合定位服务。通过使用维智定位SDK&#xff0c;开发者可以轻松为应用程序实现极速、智能、精准、高效的定位功能。 重要&#xff1a;为了进一步加强对最终用…

【CSS】使用 CSS 绘制三角形

一、Border 边框法&#xff08;最常用&#xff09; 原理&#xff1a;通过设置元素的宽高为 0&#xff0c;利用透明边框相交形成三角形。 .triangle {width: 0;height: 0;border-left: 50px solid transparent; /* 左侧边框透明 */border-right: 50px solid transparent; /* …

RabbitMQ 快速上手:安装配置与 HelloWorld 实践(一)

一、引言 在当今分布式系统大行其道的技术浪潮下&#xff0c;各个服务之间的通信与协同变得愈发复杂。想象一下&#xff0c;一个电商系统在大促期间&#xff0c;订单服务、库存服务、支付服务、物流服务等众多模块需要紧密配合。如果没有一种高效的通信机制&#xff0c;系统很容…

【deekseek】TCP Offload Engine

是的&#xff0c;TOE&#xff08;TCP Offload Engine&#xff09;通过专用硬件电路&#xff08;如ASIC或FPGA&#xff09;完整实现了TCP/IP协议栈&#xff0c;将原本由CPU软件处理的协议计算任务完全转移到网卡硬件中。其延迟极低的核心原因在于 硬件并行性、零拷贝架构 和 绕过…

JavaScript 的编译与执行原理

文章目录 前言&#x1f9e0; 一、JavaScript 编译与执行过程1. 编译阶段&#xff08;发生在代码执行前&#xff09;✅ 1.1 词法分析&#xff08;Lexical Analysis&#xff09;✅ 1.2 语法分析&#xff08;Parsing&#xff09;✅ 1.3 语义分析与生成执行上下文 &#x1f9f0; 二…

WORD个人简历单页326款模版分享下载

WORD个人简历模版下载&#xff1a;WORD个人简历模版https://pan.quark.cn/s/7e79a822c490

Android 中 显示 PDF 文件内容(AndroidPdfViewer 库)

PDFView 是一个用于在 Android 应用中显示 PDF 文档的库。它提供了丰富的功能和灵活的配置选项&#xff0c;使得开发者能够轻松地在应用中嵌入 PDF 阅读器。 一、 添加依赖 在模块的 build.gradle 文件中添加以下依赖&#xff1a; // pdfimplementation("com.github.bar…

微信小程序学习之搜索框

1、第一步&#xff0c;我们在index.json中引入vant中的搜索框控件&#xff1a; {"usingComponents": {"van-search": "vant/weapp/search/index"} } 2、第二步&#xff0c;直接在index.wxml中添加布局&#xff1a; <view class"index…