热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Redis系列(八)底层数据结构之紧凑列表

前言定义总结参考文章联系我前言Redis已经是大家耳熟能详的东西了,日常工作也都在使用,面试中也是高频的会涉及到,那么我们对它究竟了解

  • 前言
  • 定义
  • 总结
  • 参考文章
  • 联系我

前言

Redis 已经是大家耳熟能详的东西了,日常工作也都在使用,面试中也是高频的会涉及到,那么我们对它究竟了解有多深刻呢?

我读了几本 Redis 相关的书籍,尝试去了解它的具体实现,将一些底层的数据结构及实现原理记录下来。

本文将介绍 Redis 中底层的 listpack(紧凑列表) 的实现方法。 它是 Redis 的 Stream 用到的数据结构之一。


定义

Redis 设计 listpack 的目的就是取代 ziplist, 在 Redis 系列(三)底层数据结构之压缩列表 中我们提到,ziplist 在极小的概率下有可能发生级联更新,当连续规模较大的级联更新发生时,对 Redis 的性能有比较大的影响。

虽然我们都知道这是极小的概率,但是这种设计缺陷却不能被 Redis 的大佬作者所接受,因此在 5.0 版本中新引入了一个数据结构,名叫 listpack, 大家都将它翻译为 紧凑列表.

它的定义和 ziplist 极其相似,只是通过一些新的设计,来解决 ziplist 中的痛点问题。因此本文的讲解基于读者已经了解 ziplist.

ziplist的定义如下:
注意:这是 ziplist 的定义

struct ziplist<T>{// 整个压缩列表占用字节数int32 zlbytes;// 最后一个节点到压缩列表起始位置的偏移量&#xff0c;可以用来快速的定位到压缩列表中的最后一个元素int32 zltail_offset;// 压缩列表包含的元素个数int16 zllength;// 元素内容列表&#xff0c;用数组存储&#xff0c;内存上紧挨着T[] entries;// 压缩列表的结束标志位&#xff0c;值永远为 0xFF.int8 zlend;
}

listpack 的定义和上方基本一致&#xff0c;只是去掉了 zltail_offset 属性。

让我们回想一下&#xff0c;ziplist 中用这个属性做什么&#xff1f;用来方便的找到最后一个节点&#xff0c;然后方便进行反向的遍历。新的 listpack 当然是解决了这个问题&#xff0c;才能放心的删除掉这个属性。

listpack节点的定义如下&#xff1a;

int<var> encoding;
optional byte[] content;
int<var> length;

相比于 ziplist 的定义&#xff0c;它有两点改动&#xff1a;


  1. 记录的长度不再是前一个节点的长度&#xff0c;而是自己的长度。
  2. 将记录自己的长度放到了节点的尾部。

这样做的好处是&#xff1a;


  1. 不再需要 zltail_offset 属性也可以快速定位到最后一个节点。用listpac 的总长度-最后一个节点的长度.
  2. 每个节点记录自己的长度&#xff0c;当本节点的值发生了改变&#xff0c;只需要更改自己的长度即可。不再需要更改别的节点的属性&#xff0c;也就彻底的解决掉了级联更新问题。

总结

listpack 是 Redis 设计用来取代掉 ziplist 的数据结构&#xff0c;它通过每个节点记录自己的长度&#xff0c;且放在节点的尾部&#xff0c;来彻底解决掉了 ziplist 存在的级联更新的问题。

listpack 在 5.0 版本引入&#xff0c;但是由于 ziplist 在 Reids 内部的使用太过于广泛&#xff0c;有一些兼容问题&#xff0c;我们可以预见这将是一个逐步的替换过程。

同样在 5.0 版本引入的 Stream 数据结构中&#xff0c;就使用了 listpack 而不是 ziplist.


参考文章

《Redis 的设计与实现&#xff08;第二版&#xff09;》

《Redis 深度历险&#xff1a;核心原理和应用实践》

完。


联系我

最后&#xff0c;欢迎关注我的个人公众号【 呼延十 】&#xff0c;会不定期更新很多后端工程师的学习笔记。
也欢迎直接公众号私信或者邮箱联系我&#xff0c;一定知无不言&#xff0c;言无不尽。



以上皆为个人所思所得&#xff0c;如有错误欢迎评论区指正。

欢迎转载&#xff0c;烦请署名并保留原文链接。

联系邮箱&#xff1a;huyanshi2580&#64;gmail.com

更多学习笔记见个人博客或关注微信公众号 <呼延十 >------>呼延十


推荐阅读
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • Go语言实现堆排序的详细教程
    本文主要介绍了Go语言实现堆排序的详细教程,包括大根堆的定义和完全二叉树的概念。通过图解和算法描述,详细介绍了堆排序的实现过程。堆排序是一种效率很高的排序算法,时间复杂度为O(nlgn)。阅读本文大约需要15分钟。 ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 本文介绍了使用Python解析C语言结构体的方法,包括定义基本类型和结构体类型的字典,并提供了一个示例代码,展示了如何解析C语言结构体。 ... [详细]
  • Week04面向对象设计与继承学习总结及作业要求
    本文总结了Week04面向对象设计与继承的重要知识点,包括对象、类、封装性、静态属性、静态方法、重载、继承和多态等。同时,还介绍了私有构造函数在类外部无法被调用、static不能访问非静态属性以及该类实例可以共享类里的static属性等内容。此外,还提到了作业要求,包括讲述一个在网上商城购物或在班级博客进行学习的故事,并使用Markdown的加粗标记和语句块标记标注关键名词和动词。最后,还提到了参考资料中关于UML类图如何绘制的范例。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • phpcomposer 那个中文镜像是不是凉了 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 本文详细介绍了git常用命令及其操作方法,包括查看、添加、提交、删除、找回等操作,以及如何重置修改文件、抛弃工作区修改、将工作文件提交到本地暂存区、从版本库中删除文件等。同时还介绍了如何从暂存区恢复到工作文件、恢复最近一次提交过的状态,以及如何合并多个操作等。 ... [详细]
author-avatar
心痛则痛1314
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有