Redis数据结构之list对象

List 对象

一个list对象,可以看到它是quicklist编码。

127.0.0.1:6379> rpush list 1 "hello" 2 3
(integer) 4
127.0.0.1:6379> type list
list
127.0.0.1:6379> object encoding list
"quicklist"

新版本的redis的list对象都是使用quicklit编码。为了更好的理解quicklit编码,我们先介绍quicklit编码的前身,ziplist和linklist。

==ziplist和linklist都已经被quicklit所取代,这里只是为了更好的理解quicklit才列出ziplist和linklist两种编码==

ziplist编码

顾名思义,压缩链表,为了节约内存空间而设计。

一个压缩链表的结构

在这里插入图片描述

·若列表zlbytes属性的值为0x50(十进制80),表示压缩列表的总长为80字节。
·若列表zltail属性的值为0x3c(十进制60),这表示如果我们有一个指向压缩列表起始地址的指针p,那么只要用指针p加上偏移量60,就可以计算出表尾节点entry3的地址。
·若列表zllen属性的值为0x3(十进制3),表示压缩列表包含三个节点。

压缩链表的每一个节点,也就是上图的entry1,entry2结构如下

在这里插入图片描述

节点的previous_entry_length属性以字节为单位,记录了压缩列表中前一个节点的长度,也就是说当我们获取到一个指向当前节点的指针p时,么只要用指针p减去偏移量previous_entry_length就可以获得上一个节点,通过zltail属性又可快速获取最后一个节点。压缩链表通过这种方式实现从表尾向表头遍历链表。
压缩链表开辟了一块连续的空间实现了链表结构,极大的提高的内存的利用率,缺点是需要经常要重新分配内存。

ziplist编码的list对象的结构,ptr指向一个压缩链表

在这里插入图片描述

linkedlist编码

linkedlist的编码的list对象则是普通的链表结构指向相应的存储对象,图中是指向string对象。

在这里插入图片描述

优点是插入新增不需要重新分配内寸,缺点内存使用效率较低。

quicklist编码

了解了ziplist和linkedlist之后就很容易理解quicklist的结构了

quicklist就是每个linkedlist节点都存储一个ziplist对象,每个ziplist为8kb,超过8kb则新建一个节点

在这里插入图片描述

这样就极大的降低了内存的碎片化程度,又降低了内存重新分配的规模。

实际使用的时候,quicklist在不断的新增元素时,第一个quicklistNode和最后一个quicklistNode指向的ziplist始终保持不压缩的状态,而中间的ziplist会被再次压缩(执行LZF算法)。不被压缩的ziplist数量是由redis.conf中的list-compress-depth决定的,默认是一,也就是第一个和最后一个不被压缩,当ziplist满了需要新建一个quicklistNode时它的空间限制是8kb,由list-max-ziplist-size决定。

我们可以用rpush,lpush,rpop,lpop等命令操作quicklist。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Redis主要支持的数据类型有5种:String ,Hash ,List ,Set ,和 Sorted Set。 ...
    爱情小傻蛋阅读 1,441评论 0 0
  • redis的数据结构string,hash,list,set(集合),zset(有序集合) 五种数据结构,但这个只...
    IT菜鸟学习阅读 1,757评论 0 0
  • Redis的内存优化 声明:本文内容来自《Redis开发与运维》一书第八章,如转载请声明。 Redis所有的数据都...
    meng_philip123阅读 18,940评论 2 29
  • 参考来源 Redis的内存优化 Redis所有的数据都在内存中,而内存又是非常宝贵的资源。对于如何优化内存使用一直...
    秦汉邮侠阅读 1,310评论 0 2
  • 如性法师 要掌握无遮有两种的分类。然后它的分类是从他的所破来做分类,如果它的所破是存在的,它就是分成自之所遮于所知...
    任飛穎阅读 1,265评论 0 0