redis进阶之路-深入探索list

2023-02-28 13:57:59 浏览数 (2)

大家好,我是热心的大肚皮,皮哥。

redis中的list是啥?

redis中的列表相当于java中的LinkedList,注意它是链表不是数组。当列表弹出最后一个元素,该数据结构被删除,内存被回收。

  • 插入、删除 - 时间复杂度O(1)
  • 索引定位 - 时间复杂度O(N)

redis中的列表也常用做异步队列,将需要延后处理的任务数据序列化成字符串存入列表,另一个线程从这个列表中轮询数据。

先进先出:队列

代码语言:javascript复制
> rpush books python java golang
(integer) 3
> llen books 
(integer) 3
> lpop books
"python"
> lpop books
"java"
> lpop books
"golang"
> lpop books
(nil)

先进后出:栈

代码语言:javascript复制
> rpush books python java golang
(integer) 3
> llen books 
(integer) 3
> rpop books
"golang"
> rpop books
"java"
> rpop books
"python"
> rpop books
(nil)

以下慢操作使用时要格外注意。

代码语言:javascript复制
> rpush books python java golang
(integer) 3
> lindex books #O(N)慎用
"java"
> lrange books 0 -1 # 获取所有元素,O(N)慎用
1) "python"
2) "java"
3) "golang"
> ltrim books 1 -1 # O(N)慎用

list如何实现?

数据量少时,使用一块连续内存存储-ziplist(压缩链表),数据量较多时,采用quicklist存储。如下图。

压缩链表-ziplist

代码语言:javascript复制
struct ziplist<T> {
    int32 zlbytes; // 整个压缩列表占用d的字节数
    int32 zltail_offset; //最后一个元素距离起始位置的偏移量
    int16 zllength;// 元素个数
    T[] entries;//  元素内容  
    int8 zlend; // 结束位,固定值 0xFF
}

struct entry {
    int<var> prevlen;//前一个entry的长度,支持倒序遍历使用
    int<var> encoding;//元素类型编码
    optional byte[] content;//内容
}

这么设计虽然在插入操作很方便,很快,但是也有个弊端,数据都是按照这种格式紧凑的放到一起没有冗余空间,那么每次修改时都要对压缩链表进行修改,要进行级联更新

快速链表-quicklist

如果list中数据过多,那性能怎么保证呢?这时候就用到了quicklist。它是ziplist与linkedlist的组合体。

代码语言:javascript复制
struct ziplist<T> {
    ....
}

struct ziplist_compressed {
    int32 size;
    byte[] compressed_data;//内容
}

struct quicklistNode {
    quicklistNode* prev;
    quicklistNode* next;
    ziplist* zl;//对应的压缩列表
    int32 size;// ziplist的字节总数
    int16 count;// ziplist的元素数量
    int2 encoding;//存储方式,原生数组还是LZF压缩存储
    。。。
}

struct quicklist{
    quicklistNode* head;
    quicklistNode* tail;
    long count;//元素数量
    int nodes;//ziplist 节点个数
    int compressDepth;//LZF算法压缩深度
    。。。。
}

quicklist内部默认单个ziplist长度为8k字节,为了节约空间,还会对quicklist进行压缩,compressDepth为1时代表压缩深度为1,即首尾两个ziplist不压缩;compressDepth为2时代表压缩深度为2,即首尾两个ziplist不压缩及首尾第二个ziplist都不压缩。

0 人点赞