List数据结构

2 分钟阅读 391 字 + 228 词
Lists实现原理
早期作为Lists的底层实现的linkedlist(双端链表)和ziplist(压缩列表),Redis3.2引入的由 linkedlist和ziplist 组成的 quicklist ,以及7.0版本中 取代了ziplist的listpack。
linkedlist由于是链表,所以每个节点内存不连续,并且每个节点都有一个pre指针和一个next指针。
  1. 当链表中的每个元素占用的字节数小于或等于64,
  2. 当链表的元素数量小于512个
就会使用ziplist存储链表, ziplist内存是连续的 ,并使用元数据来记录了总字节数和最后一个entry的偏移量,和entry总数,能够以O(1)的时间找到ziplist中第一个元素或最后一个元素。 entry中还存储了前一个entry占用的字节数。
  1. 但是ziplist也有缺点,不能保存过多元素,否则查询性能会大大降低,导致O(N)时间复杂度。
  2. ziplist的存储空间是连续的,当插入新的entry时,内存空间不足就需要重新分配一块连续内存空间,引发 连锁更新问题。
于是Redis3.2引入了quicklist
quicklist本质还是一个链表,只不过链表的每个节点都是一个ziplist。
每个节点还是有前序指针和后序指针,由于每个节点都是ziplist,所以还有一个指向ziplist的指针。
但由于有ziplist,所以连锁更新的问题还是存在。
后序7.0版本使用listpack替换掉ziplist。 listpack不记录前一个元素的长度,而是记录自身的encoding-type和encoding-data的长度。
可用场景
消息队列:异步的服务间通信方式(异步解耦,流量削峰)