深入学习 Redis - 深挖经典数据类型之 list

news2024/12/24 9:08:33

目录

前言

一、list 类型

1.1、操作命令

lpush / rpush(插入元素)

lrange(查看范围元素)

lpushx / rpushx (有约束的插入)

lpop / rpop(头删尾删)

lindex(获取下标元素)

llen(长度)

lrem(删除指定元素)

ltrim(保留区间)

lset (根据下标修改元素)

blpop / brpop(阻塞删除)

1.2、内部编码方式

1.3、使用场景

表示多表之间的关联关系

一般消息对列

频道(多列表)消息队列

微博列表


前言


redis 中所有的 key 都是字符串,value 的类型是存在差异的,因此出现了操控不同 value 的命令,接下来,就一起来学习一下吧~

Ps1:接下来,我给出的指令都是按照 Redis 官方文档的语法格式来解析的,[ ] 相当于一个独立的单元,表示可选项(可有可无),其中 | 表示 “或者” 的意思,多个只能出现一个,[ ] 和 [ ] 之间是可以同时存在的.

Ps2:一个快速失去年终奖的小技巧 —— 清除 redis 上所有的数据 =》 FLUSHALL,这个操作可以把 redis 上所有的键值对全部带走.

一、list 类型


1.1、操作命令

 list 的内部结构类似于 “双端队列”(deque),元素是有序的,并且允许元素重复,因此头插和尾插的效率很高,可以当作一个 栈 / 队列 来使用,约定最左侧元素下标是 0,并且是是支持负数下标.

Redis 早期作为消息队列就是通过 List 来实现的,后面又提供了一种 stream 这种功能更加强大的类型来实现.

Ps:"有序" 的含义一定要根据上下文来区分,有的时候谈到有序指的是 “升序” 和 “降序” ,有的时候,指的是顺序很关键(如果把元素位置颠倒,顺序调换,那么新的 list 和之前的 list 是不对等的)~

就像面试的时候问你谈谈对 “栈 / 堆” 的理解,那么一定不要一上来就回答,而是要问清楚,到底是问数据结构中的,还是操作系统中的,还是 JVM 中.

lpush / rpush(插入元素)

lpush 和 rpush 都是用来插入元素的,分别是从左右两侧插入元素,一次可以一个或多个,例如插入 1 2 3 4 ,按照顺序使用 lpush 插入,插入完毕后,4 就是开头元素.(时间复杂度 O(1))

LPUSH key element [element ...]

lrange(查看范围元素)

查看 list 中指定范围的元素,区间为 闭区间(Redis 中的区间都是 闭区间),同样支持负数下标.

LRANGE key start stop

 Ps:Redis 中使用 lrange 如果下标超出范围,不会像 java 那样抛出异常,而是尽可能的获取到对应内容(有多少获取多少,超出的不管)

lpushx / rpushx (有约束的插入)

lpushx 表示有约束的从左侧插入一个或多个元素,只有当 key 存在时,才能将元素插入成功,不存在则插入失败,返回值为插入元素的个数(返回 0 表示插入失败).

rpushx 与 lpushx 同理,rpushx 只是从右侧插入元素.

LPUSHX key element [element ...]

 

lpop / rpop(头删尾删)

lpop 表示从最左侧删除一个元素. 

rpop 同理,从右侧删除一个元素.

LPOP key

Ps:在 redis 6.2 之后新增了一个 count 参数, count 就描述了这次要删除的元素个数.

Ps:Redis 中 list 是一个双端队列,从两头插入 / 删除元素 都是非常高效的,因此

搭配使用 rpush 和 lpop ,就相当于队列.

搭配使用 rpush 和 rpop ,就相当于栈.  

lindex(获取下标元素)

获取给定下标的对应元素,时间复杂度为 O(N),此处的 N 指的是 list 中元素个数.

LINDEX key index

 Ps:如果下标非法,返回 nil.

llen(长度)

获取 list 元素个数.

LLEN key

 

lrem(删除指定元素)

用来删除指定元素,并可以根据 count 来指定删除元素(element)的个数(list 中允许出现重复元素).

LREM key count element

当 count > 0 时,从最左侧删除元素 count 个 element 的元素

当 count < 0 时,从最右侧删除元素 count 个 element 的元素

当 count = 0 时,删除所有的 element 元素.

 

ltrim(保留区间)

LTRIM key start stop

保留 start 到 stop 之间的元素(闭区间,并且删除 闭区间 之外的所有元素)

 Redis 的官方文档中还给出了访问控制列表(redis 6 及以上版本支持),acl 就是给每一个命令都打上标签,这样管理员就可以给每一个 redis 用户配置不同的权限(允许该用户可以执行哪些命令).这不是一个知识点,只是用到的时候查一下配置怎么写.

lset (根据下标修改元素)

用来根据指定下标修改元素,处理的时间复杂度为 O(N).

LSET key index element

 

Ps:这里不会像 lindex 那样下标越界能很好的处理,lset 下标越界就会报错.

blpop / brpop(阻塞删除)

这类似于阻塞队列(BlockingQueue)实现生产者消费者模型,阻塞就表示当前的线程不再往后执行了,满足一定条件以后才被唤醒.

在 redis 中的 list 只支持 "队列为空" 的情况,不考虑 "队列满",具体规则如下:

  1. 如果 list 中 存在元素, blpop 和 brpop 就和 lpop 以及 rpop 作用完全相同.
  2. 如果 list 中为空,blpop 和 brpop 就会产生阻塞,一直阻塞到队列不为空为止.
  3. 可以显式设置阻塞时间,并且阻塞期间可以执行其他命令(阻塞期间并不会对 redis 服务器产生负面影响).
  4. 命令中若设置了多个键,那么会从左向右进行遍历,一旦有一个键对应列表中可以弹出的元素,命令立即返回.
  5. 如果有多个客户端同时执行 blpop,则先执行命令的客户端得到弹出的元素((这就像是有一个女神,但是有多个屌丝去追,当女神有空了以后,哪个先约的,哪个人就能先约到女神).

blpop 和 brpop 两个阻塞命令,主要用途就是用来做 "消息队列",但是这两命令的功能还是比较有限的(实现消息队列我们一般不用 redis).

BLPOP key [key ...] timeout

Ps:此处的超时时间,单位是 秒(redis 5), redis 6 超时时间允许设置成小数.

1.针对一个空队列进行操作,就阻塞住了~

2.再开启一个 redis 客户端,向 key1 中再塞一个元素阻塞就解除了.

 

针对多个 key 进行操作,哪个 key 先放入元素,就取哪个~

 

1.2、内部编码方式

在 redis 早期的版本中,有以下两种编码方式:

  1. linkedlist:双向链表,当一个 list 包含了数量比较多的元素,又或者 list 中包含的元素都是比较长的字符串时,Redis就会使用 linkedlist 作为 list 的底层实现。
  2. ziplist:压缩列表,当哈希表里的元素比较少的时候,就优化成了 ziplist 了,能够节省空间(压缩的原因:redis 上有很多 key,可能某些 key 的 value 是 hash,此时如果 key 特别多,对应的 hash 也特别多,但是每个 hash 又不是特别大的情况下,就尽量去压缩,让整体占用内存更小了);
     

现在的 redis 中 list 内部编码为 quicklist,包含了以上两种编码方式的有优点.

quick 相当于是 链表 和 压缩列表 的结合,整体还是一个双向链表,链表的每一个节点是一个压缩列表(控制链表每个节点不能过大).

之前的 list-max-ziplist-entries 配置 和 list-max-ziplist-value 都不在使用了,现在使用的配置是 list-max-ziplist-size .

1.3、使用场景

表示多表之间的关联关系

可以将 list 作为 "数组" 这样的结构来存储多个元素,例如现在有学生和班级两张表,使用 hash + list 的方式就可以将 学生和班级信息关联起来.

一般消息对列

通过 blpop / brpop 就可以实现生产者消费者模型.

当有多个消费者时,谁先执行 brpop 命令,谁就能先拿到元素,像这样的设定,就能构成一个 “轮询” 的效果~  

假设消费者执行顺序执行的顺序是1、2、3,当新的元素到来的时候,消费者1 就可以先拿到元素,之后 消费者1 还想继续消费,就需要重新执行 brpop ,执行后就意味 消费者1 的执行顺序被排到了最后,之后每个消费者都依次轮询...

频道(多列表)消息队列

多列表这种场景也是很常见的,例如抖音这个软件,一个通道来了可以传输短视频、另一个通道来了,可以传输弹幕、还有...这样多个通道就实现了解耦操作,互不干扰.

 

微博列表

每个用户都有属于⾃⼰的 Timeline(微博列表),现需要分页展示列表。此时可以考虑使用 列表,因为列表不但是有序的,同时⽀持按照索引范围获取元素。

分页获取用户用户前 10 个文章伪代码,如下:

keylist = lrange user:1:mblogs 0 9

for key in keylist {
 hgetall key
}

每一页有多少数据是不确定的,有可能触发很多 hgetall 操作,导致过多的网路请求

正确的解决办法就是分流水线去做,假设某个用户发了 1w 个微博,长度就是 1w ,我们就可以把中 1w 数据拆成 10 份,每个就是 1k .

 

 

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

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

相关文章

2023年第三届能源、电力与电气工程国际会议 (CoEEPE 2023)

会议简介 Brief Introduction 2023年第三届能源、电力与电气工程国际会议(CoEEPE 2023) 会议时间&#xff1a;2023年11月22日-24日 召开地点&#xff1a;澳大利亚墨尔本 大会官网&#xff1a;www.coeepe.org 2023年第三届能源、电力与电气工程国际会议(CoEEPE 2023)由安徽大学、…

使用GGML和LangChain在CPU上运行量化的llama2

Meta AI 在本周二发布了最新一代开源大模型 Llama 2。对比于今年 2 月发布的 Llama 1&#xff0c;训练所用的 token 翻了一倍&#xff0c;已经达到了 2 万亿&#xff0c;对于使用大模型最重要的上下文长度限制&#xff0c;Llama 2 也翻了一倍。 在本文&#xff0c;我们将紧跟趋…

JavaScript基础语法及小案例

目录 JavaScript基础语法1. 变量声明和赋值2. 数据类型1) 基本数据类型2) 复合数据类型(引用类型)3) 特殊数据类型 3. 运算符1) 算术运算符2) 赋值运算符3) 比较运算符4) 逻辑运算符5) 三元运算符 4. 控制流程1) 条件语句2) 循环语句 5. 函数1) 函数的基本使用① 什么是函数② …

DXFReader.NET 2023 Crack

DXFReader.NET 是一个 .NET 组件&#xff0c;允许直接从 AutoCAD 图形文件格式 DXF&#xff08;也称为图形交换格式&#xff09;查看、操作和打印。 DXFReader.NET 之 DXF 是 Drawing eXchange Format 的首字母缩写。DXF 是图形文件内容的复制&#xff0c;支持将文件从一个 CA…

机器学习深度学习——预备知识(上)

深大的夏令营已经结束&#xff0c;筛选入营的保研er就筛选了1/3&#xff0c;280多的入营总人数里面双非只有30左右。 最终虽然凭借机试拿到offer了&#xff0c;但是我感受到了自己的明显短板&#xff0c;比如夏令营的舍友就都有一篇核心论文&#xff0c;甚至还有SCI一区一作的。…

Mac应用程序因“来自身份不明的开发者”无法打开如何解决

相信不少mac电脑用户在安装应用程序时经常会遇到“xxx.app已损坏&#xff0c;打不开。这是mac系统的新的安全机制&#xff0c;安装 App 时提示&#xff1a; 常见的几种报错提示 xxx 已损坏&#xff0c;无法打开。您应该将它移到废纸篓打不开 xxx&#xff0c;因为它来自身份不明…

旋翼式水表安装注意事项

旋翼式水表是一种常用的水流计量设备&#xff0c;适用于小口径管道的单向水流总量的计量。如果你正在考虑安装旋翼式水表&#xff0c;以下是一些需要注意的事项&#xff1a; 1.安装位置的选择&#xff1a;旋翼式水表应该安装在管道的垂直方向上&#xff0c;并且水流方向必须与水…

探秘ArrayList源码:Java动态数组的背后实现

探秘ArrayList源码&#xff1a;Java动态数组的背后实现 一、成员变量二、构造器1、默认构造器2、带初始容量参数构造器3、指定collection元素参数构造器 三、add()方法扩容机制四、场景分析1、对于ensureExplicitCapacity&#xff08;&#xff09;方法1.1 add 进第 1 个元素到 …

MQTT的理解和使用

MQTT是一种基于发布/订阅模式的轻量协议&#xff0c;该协议基于TCP/IP协议上&#xff0c;由IBM在1999年发布。 流程理解&#xff1a;订阅者在订阅时会选择主题&#xff08;Topic&#xff09;和服务质量&#xff08;QoS&#xff09;&#xff0c;然后发布者发布消息&#xff0c…

matlab超前-滞后校正

1控制系统的校正 系统性能 稳定性、准确性、快速性 动态性能-超前校正 阶跃曲线、频域&#xff08;bode图&#xff09;、根轨迹&#xff08;增加零点-根轨迹左移稳定性提高&#xff09;、PID控制&#xff08;PD&#xff09; 静态性能-滞后校正 阶跃曲线、频域&#xff08…

Flink CDC MongoDB 联合实时数仓的探索实践

摘要&#xff1a;本文整理自 XTransfer 技术专家, Flink CDC Maintainer 孙家宝&#xff0c;在 Flink Forward Asia 2022 数据集成专场的分享。本篇内容主要分为四个部分&#xff1a; MongoDB 在实时数仓的探索 MongoDB CDC Connector 的实现原理和使用实践 FLIP-262 MongoDB…

Spring MVC拦截器和跨域请求

一、拦截器简介 SpringMVC的拦截器&#xff08;Interceptor&#xff09;也是AOP思想的一种实现方式。它与Servlet的过滤器&#xff08;Filter&#xff09;功能类似&#xff0c;主要用于拦截用户的请求并做相应的处理&#xff0c;通常应用在权限验证、记录请求信息的日志、判断用…

多肽试剂1801415-23-5,Satoreotide,UNII-S58172SSTS,应用在多肽标记及修饰上

资料编辑|陕西新研博美生物科技有限公司小编MISSwu​ Satoreotide&#xff0c;UNII-S58172SSTS Product structure Product specifications 1.CAS No&#xff1a;1801415-23-5 2.Molecular formula&#xff1a;C58H72ClN15O14S2 3.Molecular weight&#xff1a;1302.9 4.Packa…

【C++详解】——C++11

目录 C简介 统一的列表初始化 {}的初始化 initializer_list容器 声明 auto decltype nullptr 范围for C简介 在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1)&#xff0c;使得C03这个名字已经取代了 C98称为C11之前的最新C标准名称。 不过由于C03(TC1)主…

STM32 串口 DMA 接收任意长度数据

DMA 局限性 DMA 传输完成会产生中断告知 CPU&#xff0c;这对于固定长度的数据是没什么问题的。但是对于不定长的数据就不行了&#xff0c;DMA 一定要接收到足够多&#xff08;设定的长度&#xff09;的数据时才产生完成中断&#xff0c;如果接收到的数据量小于设定的长度&…

Linux的基础配置

配置篇 前置步骤&#xff1a;先租一个服务器或装个Linux再或者虚拟机都可以 1.安装gcc,g,gdb 在Linux下我们能用什么工具来编译所编写好的代码呢&#xff0c;其实Linux下这样的工具有很多&#xff0c;但我们只介绍两款常用的工具&#xff0c;它们分别是gcc和g. gcc和g的主要…

解决端口占用

解决办法&#xff1a; 1、换一个其它未被占用的端口 2、端口被占用了&#xff0c;先看下是哪个程序再用&#xff0c;停掉就OK了 下面演示结束端口被占用的程序的过程&#xff1a; 1、查看被占用的端口的进程 netstat -aon|findstr 端口号2、根据PID找到占用此端口的进程 ta…

Redis单机伪集群配置与搭建

目录 1. 复制6个redis配置文件到当前目录下 2. 启动每个节点 3. 判断集群是否可用 4. 初始化集群 5. 查看集群信息 6. 获取与插槽对应的节点 &#xff08;1&#xff09;手动重定向 &#xff08;2&#xff09;自动重定向 7. 故障恢复 需求&#xff1a;配置一个三主三从的集…

为什么ConcurrentHashMap不允许插入null值而HashMap可以?

为什么ConcurrentHashMap不允许插入null值而HashMap可以&#xff1f; 文章目录 为什么ConcurrentHashMap不允许插入null值而HashMap可以&#xff1f;HashMap源码ConcurrentHashMap源码为什么ConcurrentHashMap需要加空值校验呢&#xff1f;二义性问题测试代码代码分析测试结果结…

纯css3实现水波纹从中心向四周扩散动画

纯css3实现水波纹从中心向四周扩散动画 效果可用于pc端或移动端,引导用户点击,间接带来一定的转化率 示例效果 示例代码 <template><div class"zanbtn-wrap"><div click"handleClick(https://pay.aikelaidev.cn/paypage/?merchant35bdYxSx7dCUr…