欢迎光临散文网 会员登陆 & 注册

Redis的底层数据结构-List(IT枫斗者)

2023-04-07 09:50 作者:IT枫斗者-跳蚤网  | 我要投稿

Redis3.0之前:ziplist/linkedlist

Redis3.0之后:quicklist

1、ziplist

1.1、什么是ziplist?

ziplist是一个经过特殊编码的双向链表,它的设计目标就是为了提高存储效率。

1.2、ziplist结构

  • zlbytes:ziplist的长度,32位无符号整数。

  • zltail:ziplist最后一个节点的偏移量,反向遍历ziplist或者pop尾部节点的时候用来提升性能。

  • zllen:ziplist的entry(节点)个数。

  • entry:节点,并不是一个数组,然后里面存的值,而是一个数据结构。下面说。

  • zlend:值为255,用于标记ziplist的结尾。



1.3、总结

  • ziplist是为节省内存空间而生的。

  • ziplist是一个为Redis专门提供的底层数据结构之一,本身可以有序也可以无序。当作为list和hash的底层实现时,节点之间没有顺序;当作为zset的底层实现时,节点之间会按照大小顺序排列。

  • ziplist的弊端也很明显了,对于较多的entry或者entry长度较大时,需要大量的连续内存,并且节省的空间比例相对不再占优势,就可以考虑使用其他结构了。

2、linkedlist

就是双向链表,对首尾节点的定位很快,O(1)复杂度。在首位前后插入节点也是O(1)。

3、ziplist和linkedlist怎么选择?

Redis的list类型什么时候会使用ziplist编码,什么时候又会使用linkedlist编码呢?

当列表对象可以同时满足下列两个条件时,列表对象采用ziplist编码,否则采用linkedlist编码。

  • 列表对象保存的所有字符串元素的长度都小于64字节;

  • 列表元素保存的元素数量小于512个;

上述两个参数可以更改配置进行自定义。

4、quicklist

5、总结

linkedlist:

  1. 双端链表便于在表的两端进行push和pop操作,但是它的内存开销比较大;

  2. 双端链表每个节点上除了要保存数据之外,还要额外保存两个指针(pre/next);

  3. 双端链表的各个节点是单独的内存块,地址不连续,节点多了容易产生内存碎片;

ziplist:

  1. ziplist由于是一整块连续内存,所以存储效率很高;

  2. ziplist不利于修改操作,每次数据变动都会引发一次内存的realloc;

  3. 当ziplist长度很长的时候,一次realloc可能会导致大批量的数据拷贝,进一步降低性能;

quicklist:

  1. 空间换时间,之前linkedlist需要两个指针,浪费空间,我现在不用linkedlist,我都采取ziplist,然后上面封装一层quicklistnode,底层存储还是ziplist,只是空间上多了一层指针用于检索。

  2. 结合了双端链表和压缩列表的优点。


Redis的底层数据结构-List(IT枫斗者)的评论 (共 条)

分享到微博请遵守国家法律