Redis底层实现---Ziplist

Redis底层实现—Ziplist

简介

redis 是开源用C语言编写的一个远程的KV词典存储服务,里面有很多经典的设计结构对后续的设计很有启发, 其中最著名的恐怕就是排序链表的底层实现—跳表。
本次要说的是他的另外一个核心的实现,他的重要程度应该说一定程度上来说远高于跳表,他的名字就是压缩链表。

底层数据结构

Redis 有 5 种基础数据结构,分别为:string (字符串)、list (列表)、set (集合)、hash (哈希) 和 zset (有序集合) , 而这5种常见数据结构底层实现分别为:

  • string 采用SDS 或者INT 来存放
  • list 采用ziplist 或者双端链表来实现(单个元素小于64字节,总个数小于512使用ziplist)。
  • set 使用 intset 和 hashtable 两种实现。
  • hash 的编码是 ziplist 或者 hashtable。
  • zset 即是有序集合,的编码是ziplist 或者 skip-list (单个元素小于64字节,128个元素一下 用ziplist)

为啥说它

redis 底层设计结构有很多,为啥要偏偏说“它”呢?

从中不难发现,ziplist 在常见五种数据结构的底层实现中,其中有3种的底层实现都跟他相关,所以我们能看出这个设计应用有多广 而且不难发现三个特点:

  • 都是有序&集合类型数据结构的底层实现
  • 都是要求单个元素较&总元素较情况
  • 在元素个数较多的时候都有其他的代替实现

既然这些集合都有自己标准的实现,为啥非要在元素小的时候使用ziplist 作为它们的底层实现呢?

####备注:对原理不感兴趣的同学可以直接跳过原理,看最后的结论部分

原理

ziplist是由一系列特殊编码的连续内存块组成的顺序存储结构,类似于数组,ziplist在内存中是连续存储的,但是不同于数组,为了节省内存 ziplist的每个元素所占的内存大小可以不同,每个节点可以用来存储一个整数或者一个字符串。
ziplist存储结构

  • zlbytes:4个字节。记录压缩列表总共占用的字节数,在对压缩列表进行内存重分配时使用
  • zltail:4个字节。可通过这个字段快速定位到链表末尾 zllen:2个字节。记录总共有多少个entry
  • entry:具体数据的内容就存在这里 zlend:1个字节。为十六进制值0xFF,标记一个压缩列表的末尾

其中每个entry 都是一个动态结构,并非固定结构因此也可以存放hash类型结构。

hash中zip存储结构

从上图中可以看出, 其实属于一种动态数组的变种,在原有基础上增加了 尾节点位置,也是为了方便查看。

ziplist的整体设计中类似于SDS一样, 与标准的c++ STL 的vector相比申请内存没有预分配的多余空间的操作(当前本身目的就是为了节约内存,所以更不可能申请多余的内存空间)

基于ziplist 操作的时候, 读取头尾节点虽然都是O(1) 的时间复杂度。但是插入和删除都需要进行内存拷贝,复杂度为O(n), ziplist 插入和删除的最坏情况下极低概率会引起连锁反应插入复杂度为O(n2)。
这种实现比起linkedlist O(1) 的插入复杂度 肯定是比不了的,因此在元素个数比较多的时候肯定不会选用ziplist 这种实现,时间耗费太大,但是对于个数比较少的情况,由于连续内存没有指针节点浪费,节约比例比较高,所以会选用这种实现。

通过ziplist 设计其实我们依然可以发现,任何设计只有合适不合适,没有完全意义下的好与坏

结论

为了节约内存而设计的:

  • ziplist 结构主要是目标是为了解决内存浪费的情况,可以将内存充分紧凑使用,节约内存空间。
  • 但也由于是使用的连续内存,不适合存储存储太大或者元素个数太多,这样会导致申请的内存块太大,使用起来不灵活。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敦兮其若朴,旷兮其若谷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值