Redis - list 列表

news/2024/5/9 12:27:40/文章来源:https://blog.csdn.net/q322359/article/details/136944097

前言

        列表类似于 Java 中的数组或者顺序表,在 Redis 中,可以对列表两端插⼊(push)和弹出(pop),还可以获取指定范围的元素列表、 获取指定索引下标的元素等。列表是⼀种⽐较灵活的数据结构,它可以充当栈和队列的⻆⾊,在实际开发上有很多应⽤场景。
        注意:list 内部的编码方式并不是一个简单的数组,更接近于双端队列

列表两端插入和弹出操作

        约定最左侧下标为 0 ,redis 的下标支持负数下标,最右侧是 -1

列表类型的特点

a.列表中的元素是有序的

        " 有序 " 的含义要根据上下文区分,有的时候谈到有序指的是升序降序,而这里谈到的有序是指顺序很关键,列表有下标,如果把两个下标之间的值进行交换,得到的列表和之前的列表就不相同

b.列表中的元素是允许重复的

c.可以当作栈和队列来使用

        因为列表的头和尾都可以高效的插入和删除元素,所以可以做出相应的限制,当作栈和队列来使用

命令

LPUSH 将⼀个或者多个元素从左侧放入(头插)到 list 中

语法

LPUSH key element [element ...]

时间复杂度:只插⼊⼀个元素为 O(1), 插⼊多个元素为 O(N), N 为插⼊元素个数.

返回值:插⼊后 list 的⻓度

        通过上图的操作,key1 对应的列表中的数据为 4 3 2 1

        注意:如果 key 已经存在,并且 key 对应的 value 类型不是 list,那么就会报错(redis 中各种数据类型的操作都是类似的效果)

LPUSHX 在 key 存在时,将⼀个或者多个元素从左侧放入(头插)到 list 中

语法

LPUSHX key element [element ...]

时间复杂度:只插⼊⼀个元素为 O(1), 插⼊多个元素为 O(N), N 为插⼊元素个数.

返回值:插⼊后 list 的⻓度。

        上图中通过 lpushx 插入数据到列表中得到的返回值是 0 就说明了没有成功插入数据,因为该列表当前不存在

RPUSH 将⼀个或者多个元素从右侧放⼊(尾插)到 list 中

语法

RPUSH key element [element ...]

时间复杂度:只插⼊⼀个元素为 O(1), 插⼊多个元素为 O(N), N 为插⼊元素个数

返回值:插⼊后 list 的⻓度

        通过上图的操作,key 对应的列表中的数据为 1 2 3 4 5

RPUSHX 在 key 存在时,将⼀个或者多个元素从右侧放入(尾插)到 list 中

语法

RPUSHX key element [element ...]

时间复杂度:只插⼊⼀个元素为 O(1), 插⼊多个元素为 O(N), N 为插⼊元素个数.

返回值:插⼊后 list 的⻓度

LRANGE 获取指定区间的所有元素

        获取从 start 到 stop 区间的所有元素,左闭右闭。下标可以使用负数

语法

LRANGE key start stop

时间复杂度:O(N)

返回值:指定区间的元素

        -1 代表最后一个元素,所以获取 0 ~ -1 的元素相当于获取列表中所有的元素

        谈到下标,往往会关注超出范围的情况,在 Redis 中,如果给定的区间非法,比如超出下标,会尽可能的获取能获取到的内容,程序的容错能力很强

        如图,要获取 0 ~ 100 区间内的数据,而列表中只有 5 个数据,很明显 100 超出了列表的下标,但 Redis 并没有报错,而是尽可能的获取了0 ~ 100 中能够获取到的数据

LPOP 从 list 左侧取出元素(即头删)

语法

LPOP key

时间复杂度:O(1) 

返回值:取出的元素或者 nil

RPOP 从 list 右侧取出元素(即尾删)

语法

RPOP key

时间复杂度:O(1) 

返回值:取出的元素或者 nil

LINDEX 获取从左数 index 位置的元素

语法

LINDEX key index

时间复杂度:O(N) 

        应该会有读者疑惑,通过下标获取元素时间复杂度不应该是 O(1) 吗,实际上 Redis 的 list(列表)类型的内部编码不是一个普通的顺序表,所以不能按照普通的顺序表来考虑该列表

返回值:取出的元素或者 nil

LINSERT 在特定位置插入元素

语法

LINSERT key <BEFORE | AFTER> pivot element

        pivot 代表要插入数据的基准值,element 代表插入的数据

时间复杂度:O(N)

返回值:插⼊后的 list ⻓度

        万一基准值存在多个怎么办?数据要如何插入?

        如上图,当基准值 2 存在多个时,选取从左到右的第一个 2 作为基准值

LLEN 获取 list 长度

语法

 LLEN key

时间复杂度:O(1)

        获取 list 的长度并不需要遍历列表中的内容,因为 redis 为列表维护了一个变量来存储列表的长度,当要获取列表长度时,直接去获取该变量即可

返回值:list 的⻓度

BLPOP 从 list 左侧取出元素(即头删)

        LPOP 的阻塞版本

        • 在列表中有元素的情况下,阻塞和⾮阻塞表现是⼀致的。但如果列表中没有元素,⾮阻塞版本会直接返回 nil,但阻塞版本会根据 timeout,阻塞⼀段时间,期间 Redis 可以执⾏其他命令,但要求执⾏该命令的客户端会表现为阻塞状态

        • 命令中如果设置了多个键,那么会从左向右进⾏遍历键,⼀旦有⼀个键对应的列表中可以弹出元 素,命令⽴即返回。

        • 如果多个客户端同时对⼀个键执⾏ pop,则最先执⾏命令的客户端会得到弹出的元素

语法

BLPOP key [key ...] timeout

        列表 key 可以有多个,表示可以同时监控多个列表,哪个列表有数据就取哪个列表

        timeout 是阻塞的时间,阻塞时间过了以后还没有获取到数据就返回 nil

时间复杂度:O(1)

返回值:取出的元素或者 nil

BRPOP 从 list 右侧取出元素(即尾删)

RPOP 的阻塞版本(详细内容参考对 BLPOP 的介绍)

语法

BRPOP key [key ...] timeout

时间复杂度:O(1)

返回值:取出的元素或者 nil

内部编码

以前列表类型的内部编码有两种:

• ziplist(压缩列表):当列表的元素个数⼩于 list-max-ziplist-entries 配置(默认 512 个),同时 列表中每个元素的⻓度都⼩于 list-max-ziplist-value 配置(默认 64 字节)时,Redis 会选⽤  ziplist 来作为列表的内部编码实现来减少内存消耗

• linkedlist(链表):当列表类型⽆法满⾜ ziplist 的条件时,Redis 会使⽤ linkedlist 作为列表的内 部实现

        因为 ziplist 编码方式虽然节省空间,但是当元素个数较多或元素较长时会大大影响存取数据的效率,所以就需要改变编码方式为 linkedlist

        注意:上述的两种编码方式我特意加上了以前,因为现在 list(列表)的内部编码方式作出了改进,现在的内部编码方式是 quicklist ,quicklist 是 ziplist(压缩列表)和 linkedlist(链表)的结合,整体还是个链表,但链表的每个节点是一个压缩列表

        通过这种方式可以节省空间,并且压缩列表不会太长,不会明显的影响读取数据的效率

使用场景

消息队列

        Redis 可以使⽤ lpush + brpop 命令组合实现经典的阻塞式 ⽣产者-消费者 模型队列, ⽣产者客户端使⽤ lpush 从列表左侧插⼊元素,多个消费者客户端使⽤ brpop 命令阻塞式地从队列中  "争抢" 队⾸元素。通过多个客户端来保证消费的负载均衡和⾼可⽤性

        有读者可能会疑惑,消息队列的存取元素不是都应该实现阻塞吗?但 lpush + brpop 命令组合明显只实现取元素的阻塞,实际上对于 Redis 的数据类型是几乎不会出现存满的情况的,首先如果 Redis 的一个数据类型中存了太多的元素,那么对其进行操作时很容易发生阻塞,所以程序员不会让 Redis 的一个数据类型中存了太多的元素,而且 list 中最多存多少元素是可以配置的,所以通常情况下只会出现列表中没有数据的情况,不会出现存满的情况。

 Redis 阻塞消息队列模型

        哪个消费者先执行 brpop 命令,哪个消费者就先获得列表中的数据

Redis 分频道阻塞消息队列模型

        消费者可以同时监视多个列表,获取数据

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

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

相关文章

16、OpenFeign和Sentinel集成实现fallback服务降级

注&#xff1a;本篇文章主要参考周阳老师讲解的cloud进行整理的&#xff01; 1、需求说明 cloudalibaba-consumer-nacos-order83 通过OpenFeign调用 cloudalibaba-provider-payment9001 1、 83 通过OpenFeign调用 9001微服务&#xff0c;正常访问OK 2、 83 通过OpenFeign调用 …

【Redis教程0x01】入门:Windows下安装和启动Redis

什么是Redis&#xff1f; Redis 是互联网技术领域中使用最广泛的存储中间件&#xff0c;它是 Remote Dictionary Service 三个单词中加粗字母的组合。 Redis 以超高的性能、完美的文档、简洁的源码著称&#xff0c;国内外很多大型互联网公司都在用。它的版本更新非常的快&…

腾讯云2核2G服务器CVM S5和轻量应用服务器优惠价格

腾讯云2核2G服务器多少钱一年&#xff1f;轻量服务器61元一年&#xff0c;CVM 2核2G S5服务器313.2元15个月&#xff0c;腾讯云2核2G服务器优惠活动 txyfwq.com/go/txy 链接打开如下图&#xff1a; 腾讯云2核2G服务器价格 轻量61元一年&#xff1a;轻量2核2G3M、3M带宽、200GB月…

力扣-20 有效的括号详解 Java

目录 1.题目分析 2.基础知识储备 2.1 哈希表 2.2 栈的存取 3. 逻辑概要 4.源码 示例 1.题目分析 为了对比都是从内而外&#xff0c;一个个匹配&#xff0c;全部匹配成功即为有效字符 2.基础知识储备 2.1 哈希表 简单来说&#xff0c;keyvalue存储 &#xff0c;通过key…

Go打造REST Server【二】:用路由的三方库来实现

前言 在之前的文章中&#xff0c;我们用Go的标准库来实现了服务器&#xff0c;JSON渲染重构为辅助函数&#xff0c;使特定的路由处理程序相当简洁。 我们剩下的问题是路径路由逻辑&#xff0c;这是所有编写无依赖HTTP服务器的人都会遇到的问题&#xff0c;除非服务器只处理一到…

基于Google云原生工程师的kubernetes最佳实践(三)

目录 三、集群管理 利用node affinity、taint等机制管理node 通过pod affinity/anti-affinity机制将pod分配到合适的node Node分级管理 从Qos角度将Pod分级 用namespace隔离不同的环境和用户 配置RBAC权限控制 1. 遵循最小权限原则 2. 使用 Role 和 ClusterRole 分离权…

Nuxt3(项目创建)

1.官方文档 Installation Get Started with Nuxt 2.版本要求 node版本>18.0&#xff0c;建议使用偶数版本 3.安装 可采用npx或pnpm&#xff0c;本人使用的pnpm进行安装&#xff0c;如果提示npx没有安装的话使用npm install -g npx安装即可。 // 安装npx npm install…

Python爬虫学习完整版

一、什么是爬虫 网络爬虫&#xff0c;是一种按照一定规则&#xff0c;自动抓取互联网信息的程序或者脚本。由于互联网数据的多样性和资源的有限性&#xff0c;根据用户需求定向抓取相关网页并分析也成为如今主流的爬取策略。 1 爬虫可以做什么 你可以爬取网络上的的图片&#…

全国超市数据可视化仪表板制作

全国超市消费数据展示 指定 Top几 客户销费数据展示 指定 Top几 省份销费数据展示 省份销售额数据分析 完整结果

FFmpeg拉取RTSP流并定时生成10秒短视频

生成效果: 视频时长为10秒 生成格式为FLV 输出日志: 完整实现代码如下: 需要在Mac和终端先安装FFmpeg brew install ffmpeg CMake文件配置: cmake_minimum_required(VERSION 3.27) project(ffmpeg_open_stream) set(CMAKE_CXX_STANDARD 17)#头文件包目录 include_director…

IDEA 2023右下角无git分支显示解决

当你排除项目问题之后&#xff0c;可能就是idea配置问题了&#xff0c;需要在View -> Appearance -> Status Bar Widgets 中 把 git Branch 勾上。

6.windows ubuntu 子系统 测序数据质量控制。

上一个分享&#xff0c;我们对测序数据进行了质量评估&#xff0c;接下来我们需要对数据进行数据质量控制。 数据预处理&#xff08;Data Preprocessing&#xff09;&#xff1a;包括去除接头序列&#xff08;adapter trimming&#xff09;、去除低质量序列&#xff08;qualit…

jdk8中的Arrays.sort

jdk8中Arrays.sort 这里可以看到根据传入数组类型的不同&#xff0c;排序的算法是由区别的。 拆分解析 我们在平时引用的时候&#xff0c;一般只会传入一个数组&#xff0c;但是真正调用的时候&#xff0c;参数会进行补全。 public static void sort(int[] a) {DualPivotQui…

Lilishop商城(windows)本地部署【docker版】

Lilishop商城&#xff08;windows&#xff09;本地部署【docker版】 部署官方文档&#xff1a;LILISHOP-开发者中心 https://gitee.com/beijing_hongye_huicheng/lilishop 本地安装docker https://docs.pickmall.cn/deploy/win/deploy.html 命令端页面 启动后docker界面 注…

oracle docker安装

修改下载的Image的REPOSITORY和TAG属性 修改下载的Image的REPOSITORY和TAG属性&#xff1a;docker tag <IMAGE ID> <REPOSITORY NAME> docker tag 3fa112fd3642 aliyun/oracle_11g 参考网址 使用docker images时&#xff0c;可能会出现REPOSITORY和TAG均为none的镜…

网络工程师练习题6

网络工程师 综合题 计算并填写下表&#xff1a; TP地址191.23.181.13子网掩码255.255.192.0地址类型 &#xff08;1&#xff09;网络地址&#xff08;2&#xff09;直接广播地址&#xff08;3&#xff09;主机号&#xff08;4&#xff09;子网内的最后一个可用IP地址&#xf…

【高并发服务器 03】——epoll模型

epoll模型理论&#xff08;从select到epoll&#xff09; select select的算法时间复杂度略高&#xff0c;存在线性的性能下降问题&#xff08;需要遍历访问文件描述符&#xff09;。并且&#xff0c;受限于早期的内核资源的限制&#xff0c;select能够监视的文件描述符的数量…

探索智慧农业精准除草,基于高精度YOLOv8全系列参数【n/s/m/l/x】模型开发构建农田作物场景下杂草作物分割检测识别分析系统

智慧农业是未来的一个新兴赛道&#xff0c;随着科技的普及与落地应用&#xff0c;会有更加广阔的发展空间&#xff0c;关于农田作物场景下的项目开发实践&#xff0c;在我们前面的博文中也有很堵相关的实践&#xff0c;单大都是偏向于目标检测方向的&#xff0c;感兴趣可以自行…

鸿蒙网络开发学习:【ylong_http】

简介 ylong_http 构建了完整的 HTTP 能力&#xff0c;支持用户使用 HTTP 能力完成通信场景的需求。 ylong_http 使用 Rust 编写&#xff0c;为 OpenHarmony 的 Rust 能力构筑提供支持。 ylong_http 在 OpenHarmony 中的位置 ylong_http 向 OpenHarmony 系统服务层中的网络协…

【C语言】指针基础知识(二)

一&#xff0c;指针变量类型的意义 1&#xff0c;指针的类型决定了&#xff0c;对指针解引⽤的时候有多⼤的权限&#xff08;⼀次能操作⼏个字节&#xff09;。 例如&#xff1a;char* 的指针解引⽤访问⼀个字节&#xff0c;int* 的指针解引⽤访问四个字节&#xff0c;short*…