Redis远程字典服务器(5) —— list类型详解

news2024/11/14 15:20:12

目录

一,基本情况

二,list常用命令

2.1 lpush,lrange

2.2 对于“下标越界”的思考 

2.3 lpushx,rpush,rpushx

2.4 lpop,rpop

2.5 lindex,linsert,llen 

2.6 lrem

2.7 ltrim,lset

2.8 阻塞版本命令

 2.9 blpop,brpop

三,内部编码

四,应用场景

4.1 作为数组

4.2 作为消息队列


一,基本情况

  1. 列表(list)相当于数组或者顺序表,约定最左边元素下标为0,后面依次递增;但是Redis的list支持负数下标,规定最右边的下标为-1,往左依次递减,如下图:
  2. 如上图,list支持左右两边的插入和删除:lpus,lpop,rpush,rpop。
  3. 所以list内部的编码方式,并非一个简单的数组,而是接近于deque那样的双端队列

 list类型特点

  • 列表中的元素是有序的:“有序”的含义要根据上下文区分,此处的“有序”不仅仅是升序降序,指的是顺序很关键(如果把元素位置调换,得到的新的list和旧的list是不等价的;当调换后新list和旧list一样,就称之为顺序不关键),所以一个词要怎么理解,务必要结合上下文,结合具体场景去理解
  • 区分获取元素和删除元素的区别:lrem是删除,lindex是获取,两个命令的返回值是一样的,容易混淆。
  • list中的元素允许重复:像hash这样的类型,field不能重复
  • 因为当前的list,能头和尾都能插入和删除,可以把list当作一个栈或者队列来使用

二,list常用命令

命令查询文档传送门:Commands | Docs (redis.io)

2.1 lpush,lrange

lpush表示从列表左边头插元素(插入1,2,3,4,完成操作后4在最前面),可以一次插入多个,能减少网络开销;lrange作用是查询指定区间的值,有三个参数,第一个为key,第二个和第三个为指定区间的开始下标和结束下标,是一个闭区间:

要想一次查询所有元素,只需要将lrange的开始设为0,结尾设为-1即可: 

注意

  • 如果key已经存在并且对应的value不是list,那么lpush就会报错 
  • lrange前面显示的序号和下标无关,是专门给结果集使用的序号,给我们看的。(hash类型操作也有这样的序号,但是也和下标无关,因为hash没有下标的概念)

2.2 对于“下标越界”的思考 

问题:谈到下标,往往会有“超过范围”这样的情况,如何理解?

解答: C++中,下标超出范围,一般会认为这是一个“未定义行为”,可能会导致程序崩溃,也可以会得到一个不合法的数据,还有可能会得到一个“看起来合法,但是错误”的数据,还有可能得到符合要求的数据(类似开盲盒);而在Java中,下标超出范围,一般会“抛异常”。

而在Redis中,两种行为都为采用,如果区间是合法的就正常搞,如果不合法,就直接尽可能去获取对应的内容,这种处理方式接近于Python的“切片”的处理方式。

比如,盆友找我借100,但是我只有50,盆友说:“50就50吧,借我一下谢谢”,能给多少给多少这样。

C++和Java对于越界的处理方式,有哪些优点缺点呢?

C++的处理方式:

  • 优点:效率是最高的,因为Java要抛异常,就代表Java要多出一步“下标合法性验证”的步骤,做的工作多了,效率就低了
  • 缺点:程序员不一定能第一时间发现问题,而且很难发现,就导致最后的结果是“带伤运行”,最后越积越多,导致严重后果

Java的处理方式:

  • 优点:出现问题能及时发现
  • 缺点:效率没C++高,因为多了一步

Redis或Python的处理方式,是一种更加柔和式的做法,称之为“鲁棒性”(你对我越粗鲁,我就表现得越棒),这样的设定能大大提高程序的“容错性”,但是也有代价,所以这三种方式的实现,还是需要集合具体场景去搞

2.3 lpushx,rpush,rpushx

lpushx作用是,如果key存在,就头插操作,如果不存在就什么都不做;rpush就是尾插,其余机制和lpush一样;rpushx和lpushx的作用一样,只是变成了尾插:

问题:有lrange,有没有rrange呢?

解答:没有,因为lrange,延长来说是list range,不是left range 

2.4 lpop,rpop

lpop头删,,当key不存在,返回nil;rpop尾删,当key不存在,返回nil

注意

在从Redis 6.2 版本中,新增了count参数,但是当前的Redis 5 版本没有,count表示一次要删除几个数,因为一次只删一次相比一次删多个效率确实低了点  

2.5 lindex,linsert,llen 

lindex作用是根据下标来获取元素,下标非法返回nil;linsert就是在指定下标插入元素,可以自定义在左边插入还是在右边插入,下标非法返回nil;llen返回list长度,key不存在返回0:

lindex: 

linsert: 

linsert key BEFORE|AFTER pivot element

先从左往右根据基准值找到符合要求的位置,再进行插入 

llen

2.6 lrem

lrem key count element

count表示要删除的个数,element表示要删除的值

关于count还有一些说法,官方文档给出的解释如下:

解释一下: 

  • 当count > 0:从左往右去找,比如list值为“1 2 3 4 1 2 3 4 1 2 3 4”,count为2,element为1,表示从左往右找1,删两次1,结果变成“2 3 4 2 3 4 1 2 3 4”,前面两个1被删除
  • 当count < 0:从右往做找,以上面的为例,count为-2,element为1,表示从右往左找两个1删除,最后变成“1 2 3 4 2 3 4 2 3 4”,后面的两个1被删除
  • 当count = 0:删除所有的指定元素,还是以上面的为例,count为0,element为1,就找到所有的1删除,结果为“2 3 4 2 3 4 2 3 4

2.7 ltrim,lset

ltrim作用也是删除元素,但是是反过来的,指定一个区间,保存这个区间里的元素,区间外的就删除,区间不合法时返回0;lset作用是根据下标修改元素:

ltrim: 

在官方文档中查询ltrim时,还有一个东西: 

  1. 其中ACL全程是access control list,访问控制列表,是一个和权限相关的东西,从Redis 6 版本开始支持
  2. Redis有很多命令,acl这块就把每个命令打上一些标签,比如上面的@write表示这是一个“写”命令,@list表示这是一个和list类型相关的命令,@slow表示这个命令可能会很耗时
  3. 打好标签之后,管理员给每个Redis用户配置不同的权限,让该用户执行“能执行”的命令

lset: 

lset key index element

index表示要开始修改的下标位置,element表示要修改的元素

2.8 阻塞版本命令

阻塞:当前的线程不走了,代码不继续执行了,在满足一定条件后被唤醒

blpop,brpop是阻塞命令中两个最重要的,前面的b表示block阻塞

我们在学习生产者消费者模型时,讲到了一个阻塞队列:Linux系统编程——生产者消费者模型_编程 消费者-CSDN博客

 用队列来作为交易场所,并且希望这个队列有两个特性:1,线程安全    2,阻塞:

  • 如果队列为空,此时尝试出队列,就阻塞,直到队列不为空,阻塞接触
  • 如果队列为满,此时尝试入队列,就阻塞,直到队列不为满,阻塞接触

Redis中list也相当于一个阻塞队列, 首先线程安全通过单线程模型能保证,而阻塞只支持“队列为空”的情况,不考虑“队列为满”。

blpop 和 brpop 是 lpop 和 rpop 的阻塞版本,和对应⾮阻塞版本的作⽤基本⼀致,除了:

  • 在list不为空的情况下,blpop 和 brpop 就和 lpop 和 rpop作用一样;但如果list为空,blpop 和 brpop就会阻塞住,直到队列不为空
  • 使用blpop 和 brpop 的时候,是可以设置阻塞时间的,如果阻塞了,那么在这个阻塞时间内是可以执行其它命令的;当阻塞时间到了,会自动返回(例子:我约女生晚上6点吃饭,结果我等到9点女生还没来,我就不等了,及时止损,节约我的时间)
  • blpop 华人 brpop 都是可以同时去获取多个key的列表的元素的,就是命令行可以同时出现多个key的,这多个list哪个有元素了,就会返回哪个值(例子:我可以同时约多个女生出来吃饭,哪个女生先到了我就和哪个去吃饭,其她的不管了)
  • 如果多个客⼾端同时多⼀个键执⾏ pop,则最先执⾏命令的客⼾端会得到弹出的元素(例子:多个人约女生,当女生有空时,哪个人最先约的女生,女生就和谁去吃饭)

 2.9 blpop,brpop

blpop key [key ...] timeout
  1. blpop的选项和brpop是一样的,可以指定多个key,每个key都对应一个list,如果这些list有任意一个非空,blpop和brpop都能够把这里的元素获取到立即返回,
  2. 如果list都为空,就会阻塞住,等待其他客户端往list插入数据;
  3. 另外还可以指定超时时间,单位为秒;在Redis 6 版本后,允许设为小数 

我们先针对一个非空的list进行操作:

 

  • 返回的结果是一个pair,一方面告诉我们你当前的数据来自于哪个key,另一方面告诉我们取到的数据是啥

我们针对空的列表进行操作: 

我们删掉key后,在blpop就阻塞住了,然后我们在右边的客户端一创建key, 左边的客户端就立马拿到了数据,brpop作用和现象和blpop一样,就不做演示了

这两个阻塞命令,用途主要就是来作为“消息队列”,但是我们一般不使用,因为前面也说过了,Redis不适合拿来做消息队列,因为有其他更好的产品可以用作消息队列,而且提供的功能也比较多

三,内部编码

旧版本是用ziplist和linkedlist作为底层实现的,但是现在已经不用了,直接用的quicklist来实现了,但是我们去查一些文档时,上面可能还是解释的ziplist和linkedlist,所以我们只简单了解下这两个,重点还是在quicklist:

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

quicklist相当于链表和压缩列表的结合,整体是一个链表,但是它的每个节点是一个压缩列表(每个压缩列表都限制大小,然后再把多个压缩列表通过链式结构组织起来,就是quicklist)

 

四,应用场景

4.1 作为数组

最经典的,就是用list作为“数组”来存储多个元素

4.2 作为消息队列

虽说Redis不经常用来做消息队列,但毕竟是Redis设计的初心,了解一下有利于了解Redis的发展 

多个客户端执行brpop操作,当列表为空时,brpop就会阻塞住,一旦有新元素来了,谁先执行的brpop命令,谁就能拿到这个新来的元素,像这样的设定,就能构成一个“轮询”式的效果。

假设消费者执行的顺序是1 2 3:

  1. 当新元素到达后,首先是消费者1最先执行的brpop,所以它最先拿到元素,然后brpop执行执行完了直接返回,假设线程1还想继续消费,就需要重新执行brpop,重新去排队
  2. 然后再来一个新元素,就是消费者2拿到元素,也从brpop返回,要想再拿数据也需要重新排队
  3. 再来一个新元素,就是消费者3拿到元素了

将上面的模型扩大一下,就是下面这样的了: 

 因为多个 列表或者频道是非常常见的,比如抖音,需要有一个通道来传输视频数据,还有传输弹幕,传输点赞收藏转发,传输评论数据等等,都需要一个频道来传输,因为像这样搞成多个频道,就可以在一个数据通道发生问题时,不会对其他数据造成影响(解耦合

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

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

相关文章

【JavaEE】深入浅出:Spring Boot配置文件全解析

目录 SpringBoot 配置⽂件配置⽂件作⽤SpringBoot配置⽂件 配置⽂件快速⼊⼿配置⽂件的格式properties 配置⽂件说明properties 基本语法读取配置⽂件properties 缺点分析 yml 配置⽂件说明yml 基本语法yml 使⽤进阶yml 配置不同数据类型及 null配置对象配置集合配置Map yml优缺…

clickhouse集群+Zk优化-解决只读模式,主节点磁盘增长快

问题1&#xff1a;数据库进入只读模式 最近在项目中使用clickhouse的时候&#xff0c;遇到了一个批量插入后报错的问题。报错的内容是数据库进入了只读模式&#xff0c;导致数据写不进去。发现有大量的批量写入报错日志信息。&#xff08;关键异常信息&#xff1a;DB::Exceptio…

数据库行转列

一、行转列 1、使用case…when…then 2、使用SUM(IF()) 生成列 3、使用SUM(IF()) 生成列 WITH ROLLUP 生成汇总行 4、使用SUM(IF()) 生成列&#xff0c;直接生成汇总结果&#xff0c;不再利用子查询 5、使用SUM(IF()) 生成列 UNION 生成汇总行,并利用 IFNULL将汇总行标题…

【安卓】Service生命周期与前台活动

文章目录 Service生命周期使用前台Service 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。 点击跳转到网站。 Service生命周期 在项目的任何位置调用了Context的startService()方法&#xff0c;相应的Se…

安卓好软-----开源的跳开屏广告工具 无需root 权限

GKD 开源项目。 目前最新版本是1.8.0 这款工具是一款免费开源简洁多规则的自动跳过广告的软件。简而言之&#xff0c;基于预设的定时更新订阅规则快照功能&#xff0c;实现识别并自动点击跳过任何开屏广告及点击关闭应用内部任何弹窗广告&#xff0c;如关闭某些APP开屏和内含推…

ITSS服务经理与ITSS服务工程师的岗位职责分析

信息技术服务标准&#xff08;ITSS&#xff09;是一套全面而系统的规范&#xff0c;旨在指导和标准化信息技术服务的提供。 由信息技术服务标准工作组精心制定&#xff0c;这些标准不仅总结了行业的最佳实践&#xff0c;还提升了从事信息技术服务研发与应用的各类组织自主创新…

iOS的App启动详细过程(底层知识)

1.虚拟内存 & ASLR 在早期计算机中数据是直接通过物理地址访问的&#xff0c;这就造成了下面两个问题 1.内存不够用 2.数据安全问题 内存不够 ---> 虚拟内存 虚拟内存就是通过创建一张物理地址和虚拟地址的映射表来管理内存&#xff0c;提高了CPU利用率&#xff0c;…

【Python快速入门和实践012】Python常用脚本-目标检测之查看数据集标签类别及对应数量

一、功能介绍 这段代码的功能是从指定的目录中读取所有的XML文件&#xff0c;并统计这些文件中特定标签&#xff08;<object>标签内的<name>标签&#xff09;的内容和出现次数。 二、代码 import os import xml.etree.ElementTree as ET import globdef count_nu…

SAK-TC277TP-64F200N DC:32位RAM微控制器、常用于消费者应用

描述&#xff1a; SAK-TC277TP-64F200N DC属于第一代Aurix TC27xT产品。其创新多核心架构基于多达三个独立32位TriCore CPU&#xff0c;专为满足极高的安全标准&#xff0c;同时大幅提高性能而设计。TC27xT系列产品配备200 MHz TriCore、5V 或3.3V 单电压供电和强大的通用定时器…

【Linux】中的软件安装:深入探索RPM、SRPM与YUM

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Linux &#xff1a;从菜鸟到飞鸟的逆袭》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、Linux的起源与发展 2、RPM、SRPM与YUM的简要介…

【Redis】数据类型详解及其应用场景

目录 Redis 常⻅数据类型预备知识基本全局命令小结 数据结构和内部编码单线程架构引出单线程模型为什么单线程还能这么快 Redis 常⻅数据类型 Redis 提供了 5 种数据结构&#xff0c;理解每种数据结构的特点对于 Redis 开发运维⾮常重要&#xff0c;同时掌握每种数据结构的常⻅…

【大数据】智慧园区大数据云平台整体建设方案(Word原件)

第一章 项目建设背景及现状 第二章 园区创新发展趋势 第三章 工业园区大数据存在的问题 第四章 智慧工业园区大数据建设目的 第五章 智慧园区总体构架 第六章 系统核心组件 第七章 智慧工业园区大数据平台规划设计 获取方式&#xff1a;本文末个人名片直接获取。 软件资料清单列…

springboot使用aop或Jackson进行数据脱敏

1.aop 启动类加EnableAspectJAutoProxy 自定义注解&#xff0c;在实体类中使用表示被脱敏字段 建立aop切面类 可能这里gpt会建议你用Pointcut("execution(public * com.xx.aop..*.get*(..))")这种方式拦截&#xff0c;这种我试了&#xff0c;拦截不住。猜测在mvc返…

灵办AI免费ChatGPT4人工智能浏览器插件快速便捷(多功能)

灵办AI就是您所需的最佳助手&#xff01;我们为您带来了一款多功能AI工具&#xff0c;不仅能为您提供精准翻译&#xff0c;还能满足您的对话需求、智能续写、AI搜索、文档阅读、代码生成与修正等多种需求。灵办 AI&#xff0c;真正让工作和学习变得轻松高效&#xff01; 推荐使…

Android高版本抓包总结

方案1 CharlesVirtualXposedJustTrustMe 推荐使用三星手机此方案 VirtualXposed下载链接&#xff1a;https://github.com/android-hacker/VirtualXposed/releases JustTrustMe下载链接&#xff1a;https://github.com/Fuzion24/JustTrustMe/releases/ 下载完成后使用adb命令…

我的吃鸡日志 中2 从菜鸟到专家

hey&#xff0c;我又来啦&#xff01; 我的吃鸡日志中1之复仇计划见这个。 &#xff08;游戏入口&#xff1a;和平精英38.0 快乐星空&#xff09; 苦学两年半。。。。。。 hey hey hey&#xff0c;这次我必须赢&#xff01; 打开游戏ing。。。。。。 作战ing。。。。 先在…

43-设计规则:铺铜规则

1、铺铜规则设置 铺铜规则[plane]&#xff1a; PowerPlane Connect Style[负片层连接方式]: PlaneConnect&#xff1a;Direct Connect/ 高级设置->过孔改成完全连接 Power Plane Clearance[负片层间距设置]: PlaneClearance&#xff1a; 8mil Polygon Connect Style[正片层…

电动汽车和混动汽车DC-DC转换器的创新设计与测试方法

汽车 DC-DC 转换器市场规模将达到187亿美元&#xff0c;年复合增长率为10%。 DC-DC 转换器是汽车的重要组成部分&#xff0c;它可以通过电压转换为各种车载系统供电&#xff0c;例如日益复杂的车载信息娱乐系统、使用驾驶辅助系统&#xff08;ADAS&#xff09;实现的增强安全功…

VMware虚拟机H群晖7.2懒人包

目录 0. 准备 1. 下载 2. 解压 3. 导入VMware 4.开机 5.查找设备 6.登录初始化 随着DSM系统的升级,群辉NAS很多组件变哈很大,有的已经放弃不再支持,有的与其它功能合并,甚至新开发的组件仅仅支持DSM7以上。为了体验新的组件,因此有必要再安装依噶DSM7.x以上的群辉,…

领域自适应

领域自适应 迁移学习的核心思想在于&#xff0c;一个任务上训练得到的模型所包含的知识可以部分或全部地转移到另一个任务上。这种知识转移可以是网络参数、特征表示、数据间的关系等。通过迁移学习&#xff0c;我们可以利用已有的知识和经验来加速新任务的学习过程&#xff0…