Redis:list类型

Redis:list类型


几乎每种语言都有顺序表数组链表这样的顺序结构,Redis也做出了相应的支持。

如图,Redisvalue值可以是一个列表list,其支持头尾的插入删除,下标访问等功能。也支持正负数下标,正数下标从0开始,负数下标从-1开始。


list命令

非阻塞

LPUSH
  • 头插元素到list中,如果key不存在就创建
bash 复制代码
lpush key element [element ...]

返回list插入后的长度。如果一开始key不存在,就创建一个key


LRANGE
  • 获取指定范围的list元素
bash 复制代码
lrange key start stop

访问区间为[start, end]的闭区间,支持负数下标。

示例:

接下来通过lrange测试刚刚的lpush接口:

由于lpush是头部插入,所以按顺序插入1 2 3 4 5,最后存储顺序为5 4 3 2 1

如果在Redis中数组越界,Redis不会报错,而是尽可能输出范围内存在的数据。

第一次查询0 - 100,但是list中只有0 - 4,那么此时把0 - 4全部输出。第二次查询50 -60list内没用这部分数据,但是它不报错,而是输出empty表示空。


LPUSHX
  • key存在,头插元素到list
bash 复制代码
lpushx key element [element ...]

返回插入后,list中元素的个数。

示例:

第一次插入list1,由于已经存在,此时插入成功,返回9表示当前有九个元素。第二次插入了一个不存在的list2,但是它不存在,返回0表示插入后一个元素也没有,也就是插入失败。


RPUSH
  • 尾插元素到list中,如果key不存在就创建
bash 复制代码
rpush key element [element ...]

返回插入后list元素个数。

示例:

同样插入1 2 3 4 5,顺序与之前lpush插入刚好是反着的,因为rpush是尾插。

此处list有一个命名上的注意点:

  • lpushleft push,从左侧插入,即头插
  • rpushright push,从右侧插入,即尾插
  • lrangelist range,输出列表指定范围

同样是l开头,有时候表示list,有时候表示left,这个要注意。

另外的:

  • lpushxleft push exists,存在时插入

此处的x是选用了exsis中的一个字母,表示只有key存在才插入。


RPUSHX
  • key存在,尾插元素到list
bash 复制代码
rpushx key element [element ...]

返回插入后,list中元素的个数。


LPOP
  • 头删list元素
bash 复制代码
lpop key [count]

返回被删除的头部count个元素,如果list为空,没有可以删的元素了,返回nil

示例:

先创建一个1 2 3 4 5的列表,第一次lpop不带任何参数,只输出一个头部元素。第二次带参数4,此时输出剩余的四个元素。最后一次lpop,由于已经没有元素了,返回nil


RPOP
  • 尾删list元素
bash 复制代码
rpop key [count]

返回被删除的尾部count个元素,如果list为空,没有可以删的元素了,返回nil


LINDEX
  • 获取指定下标的元素
bash 复制代码
lindex key index

返回指定下标的元素,支持负数下标。

示例:


LINSERT
  • 在指定位置插入元素
bash 复制代码
linsert key before|after pivot element

在元素pivot的前面或者后面插入element元素。

示例:

此处指令的作用是,在元素c前面插入hello

如果有多个pivot元素,那么只在第一个元素的位置插入。


LLEN
  • 获取list的长度
bash 复制代码
llen key

返回list长度,如果不存在则返回0


LREM
  • 删除元素
bash 复制代码
lrem key count element

删除countelement元素。

此处count的取值有三种:

  • count > 0:从左往右删除
  • count < 0:从右往左删除
  • count = 0:删除所有元素

示例:

此处插入了1 2 3 hello循环四次,删除3 hello,即从左往右删除三个hello每次出只有最后一个hello被保留。

如果传入-3 hello,此时从右往左删除,只有第一个hello被保留。


LTRIM
  • 指定范围内元素保留,剩余的元素删除
bash 复制代码
ltrim key start stop

只保留[start, stop]闭区间内部的元素,其余的元素全部删除。

示例:


LSET
  • 修改指定下标的元素
bash 复制代码
lset key index element

将下标为index的元素改为element,支持负数下标。如果下标越界,会返回一个报错。

示例:

第一次修改,将下标为3的元素修改为666。第二次插入,操作下标为100的元素,由于不存在,报错了。


阻塞

先前的所有的命令,都是非阻塞的,直接操作就可以得到结果,而list还提供了一些阻塞性质的命令。

在多线程中,有一个生产消费模型,其可以基于阻塞队列实现,主要满足以下两个性质:

  1. 如果阻塞队列满了,那么生产者阻塞
  2. 如果阻塞队列空了,那么消费者阻塞

Redis中,list只考虑队列为空的情况,也就是消费者。用户读取数据时,队列为空,那么用户陷入阻塞,直到队列有数据。

BLPOP
  • 读取并删除list头部元素,如果没有元素则陷入阻塞
bash 复制代码
blpop key [key ...] timeout

blpop可以同时指定多个key,也就是多个list,只要任何一个list有数据,就返回结果。还可以设置超时时间timeout,以秒为单位,如果超过时间了,返回nil

如果超时时间设置为0,则一直阻塞,不会超时。

另外的,此处的阻塞不是Redis阻塞,而是客户端阻塞。如果阻塞,Redis将指令放到后台去等待,自己去执行其他指令。

示例:

此处list8有元素,而list9为空,返回了list8的元素。此时会同时返回两个内容,list8表示该数据是从哪一个列表中拿到的,3则是拿到的数据。

此处启用了两个客户端,左侧客户端blpop一个空列表,等待20s,随后陷入阻塞。接着右侧客户端插入一个元素到list9,随后左侧客户端立刻拿到数据并输出,并且输出了自己的阻塞市场18.15s


BRPOP
  • 读取并删除list尾部元素,如果没有元素则陷入阻塞
bash 复制代码
brpop key [key ...] timeout

总结:

操作类型 命令
添加 rpushlpushinsert
查找 lrangelindexllen
删除 lpoprpoplremltrim
修改 lset
阻塞 blpopbrpop

内部编码

压缩列表是一种内存紧凑的存储方式,适合存储数量较少且元素较小的列表。具体来说,当list类型的元素个数小于 list-max-ziplist-entries (默认 512 个),并且所有值的长度都小于 list-max-ziplist-value (默认 64 字节)时,Redis 会使用 ziplist 作为列表的内部实现。

这些配置在/etc/redis/redis.conf内修改。

优点:

  1. 内存节省ziplist 使用连续的内存块来存储数据,这种紧凑的存储方式可以有效地减少内存碎片和开销。
  2. 结构简单:适合小规模数据,尤其是在内存资源有限的情况下。

缺点:

  1. 操作效率 :随着数据量的增加,ziplist 的读写效率会下降。尤其是在需要频繁更新的场景中,ziplist 的线性查找特性使得操作复杂度较高。
  2. 扩展性差:不适合大规模数据存储。

linkedlist

当列表类型无法满足ziplist的条件时,会使用linkedlist链表作为list的内部实现。这就是一个基本的双向链表。

优点:

  1. 头尾的插入删除非常高效

缺点:

  1. 中间部分的插入删除时间复杂度较高

quicklist

linkedlistziplist 编码在 Redis 4.0 版本之后不再是默认的列表编码方式,因为引入了更高效的 quicklist 编码,它是基于压缩列表和双向链表的组合,旨在结合两者的优点。

对于quicklist,其外层列表依然是linkedlist双链表结构,但是每一个链表节点都是一个quicklist,对于中间部分的节点,会进行一定程度的压缩,提高效率。


相关推荐
鸠摩智首席音效师8 小时前
MySQL ERROR 1114 (HY000): The table is full
数据库·mysql
数据大魔方8 小时前
【期货量化实战】豆粕期货量化交易策略(Python完整代码)
开发语言·数据库·python·算法·github·程序员创富
Codeking__9 小时前
Redis的value类型介绍——zset
数据库·redis·缓存
muddjsv9 小时前
SQLite3 核心命令全解析 (从入门到精通)
数据库
難釋懷9 小时前
认识NoSQL
数据库·nosql
xiaolyuh1239 小时前
Redis 核心业务流程
java·redis·spring
亿坊电商9 小时前
利于SEO优化的CMS系统都有哪些特点?
前端·数据库
阿阿阿安9 小时前
MySQL(一)数据库风险操作场景总结
数据库·mysql
心丑姑娘9 小时前
使用ClickHouse时的劣质SQL样例
数据库·sql·clickhouse
↘"LYong9 小时前
Centos升级Redis(7.4.1 ---> 7.4.6)
linux·redis