Redis基础数据结构-list

Posted AI程序

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis基础数据结构-list相关的知识,希望对你有一定的参考价值。

1、说明

Redis的列表相当于java中的LinkedList,它是一个链表,也就是说list的插入和删除操作非常快,但是索引定位会比较慢。

当列表中最后一个元素被弹出后,该数据结构会被自动删除,内存被回收。

2、内部实现

list内部是一个双向链表,每个元素都使用双向指针顺序,串起来可以同时支持前向,后向遍历。

结构示意图:

3、操作命令

命令 描述
BLPOP key timeout 移出并获取列表的第一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
BRPOP key timeout 移出并获取列表的最后一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
LINDEX key index 通过索引获取列表中的元素
LLEN 获取列表长度
LPOP key 移出并获取列表的第一个元素
LPUSH key value1 [value2 ...] 将一个或者多个值插入到列表的头部
LPUSHX key value 将一个值插入到已存在的列表头部,如果列表不存在,则返回0
LRANGE key start end 获取列表指定范围内的元素
LSET key index value 通过索引设置列表元素的值
LTRIM key start end 对一个列表进行删减,只保留指定范围内的元素,不在范围内的元素将被删除
RPOP key  移出列表中的最后一个元素
RPUSH key value1 [value2 ...] 将一个或多个元素插入到列表的尾部
RPUSHX key value 将一个值插入到已存在的列表尾部,如果列表不存在,则返回0
LREM key count value 根据count值,移出列表中与参数value相等的元素。count > 0: 从表头开始向表尾搜索,移出与value相等的值,数量为count; count < 0:从表尾开始向表头搜索,移出与value相等的值吗,数量为count的绝对值;count = 0:移出表中所有与value相等的值

4、应用场景

4.1 消息队列

队列是先进先出的数据结构,可用于消息排队和异步处理的操作,它会确保元素的访问顺序。

操作:RPUSH将元素插入到列表中的最后一个元素,然后LPOP获取列表的第一个元素

4.2 栈

栈是先进后出的数据结构,和队列正好相反,它会确保最后一个存储的会第一个出现。

操作:RPUSH将元素插入到列表中的最后一个元素,然后RPOP获取列表的最后一个元素

5、注意

由于Redis的列表相当于Java的linkedlist,因此它的一些方法需要对链表进行遍历,因此在使用的时候需要特别进行注意。

5.1 LINDEX

lindex相当于Java链表的get(index)方法,它需要对链表进行遍历,性能随着参数index的增大而变差,因此在使用的时候要慎用,时间复杂度为o(n)。

5.2 LRANG key 0 -1

获取0到-1范围内的元素,即获取所有的元素,因此需要慎用,时间复杂度为o(n)。

5.3 LTRIM key 1 -1

保留从1到-1区间内的元素,区间之外的统统砍掉。但-1表示倒数第一个,该操作即保留所有的元素,因此需要慎用,时间复杂度为o(n)

6、快速列表

由于普通的列表需要一个向前指针prev和一个向后的指针next,这2个指针就要占用16个字节(64位操作系统的指针占8个字节),这样链表的附加空间相对太高;并且链表中每个节点的内存都是单独分配的,会加剧内存的碎片化,影响内存管理效率。

因此将linkedlist按段切分,每一段使用压缩列表ziplist让存储紧凑,并且根据压缩深度对ziplist进行压缩存储,然后多个ziplist之间再使用双向指针串接起来,从而组成了我们需要的quicklist快速列表。

6.1 压缩列表

压缩列表是一块连续的内存空间,元素之间紧挨着存储,没有任何冗余空隙。调试看下:

127.0.0.1:6379> lpush list k1 k2 k3
(integer) 3
127.0.0.1:6379> LLEN list
(integer) 3
127.0.0.1:6379> debug object list
Value at:00007FCD53D1D570 refcount:1 encoding:ziplist serializedlength:24 lru:15778389 lru_seconds_idle:5
127.0.0.1:6379>

我们可以看到输出的encoding为ziplist,这就表示内部采用的是压缩列表结构进行存储。

压缩列表的数据结构为:

1 struct ziplist<T> {
2     int32 zlbytes;
3     int32 zltail_offset;
4     int16 zllength;
5     T[] entries;
6     int8 zlend;
7 }

其中的字段含义:

  • zlbytes:表示的是整个压缩列表占用字节数;
  • zltail_offset:表示的是最后一个元素距离压缩列表起始位置的偏移量,用于快速定位到最后一个节点,然后倒着遍历
  • zllength:存储的元素个数
  • entries:元素内容列表,依次紧凑存储
  • zlend:标志压缩列表的结束,值恒为 0xFF

6.2 压缩深度

quicklist默认的压缩深度为0,也就是不压缩。当为1时,则表示首尾2个ziplist不压缩,为2时,表示首尾第一个和第二个ziplist不压缩。

 

以上是关于Redis基础数据结构-list的主要内容,如果未能解决你的问题,请参考以下文章

Redis基础数据结构-list

Redis02Redis基础:List相关操作

Redis学习笔记- 基础篇-基础结构及语法

redisredis的基础入门(linux)

Redis学习笔记- 基础篇-基础结构及语法

Redis学习笔记- 基础篇-基础结构及语法