在上一篇文章中,我们研究了REDIS SDS数据结构的实施原理,并分析了其目标优化方法。在本文中,我们研究了另一种数据结构Ziplist。
早期审查:[REDIS源代码系列] Redis6.0数据结构详细说明说明-SDS章节
整体布局Ziplist没有结构定义,官方文档对此进行了描述:特殊结构的两条链接列表。它的特殊位置是没有使用两个 - 道路指针(prev,Next)连接之前和之后的元素,但是通过计算特定编码元素中的长度偏移以及源代码中的注释描述来访问不同的元素。
我们可以理解,典型压缩列表的布局是:
组成以下部分:
条目对条目的逻辑定义如下:
它不是实际的存储结构,而是辅助结构。它可以通过一些宏定义更方便地扩展,简化为更易于理解内存布局,如下所示:
pre_entry_lengthpre_entry_length记录可以占据1或5字节的上一个节点的长度。当句子在当前节点的当前单词中的句子高达254时,将第一个字节设置为第一个字节以节省其值。254,其余字节保持其实际长度。通过指针偏移的第二个记录节点。如上图所示,当前的指针位置为curptr,然后preptr = curptr-pre_entry_length可以快速找到以前的节点。请参阅源代码如下:
Lenlen由两个部分组成:编码&Len,长度可能为1,2,5字节。它们在它们中,编码两个字节,其值如下:
1个字节长度小于或等于63个字节阵列2字节长度小于或等于16383字节。BIT具有符号整数1字节1字节8位,符号整数1 Byte4 Bit unsigned Integer。从怨恨到上述结构分析,我们可以理解进入布局的基本组成。,旧规则,请出现在舞台上:
图中显示了存储在Hello World中的Ziplist节点,该节点占据了两个数字,00标识了字符数组的类型,占据了6个数字,即二进制11,代表内容字节长度。编码和长度占据字节。
创建Ziplist
创建方法相对简单。可以看出,它本质上是一个字节数组。初始化的内存为: += 11个字节,宏如下:
插入元素方法的上游和方法调用中有一个执行方法。源代码分析如下:
根据上面的分析查找元素,我们可以比较Ziplist的发现操作。源代码分析如下:
我们在链更新之前分析的属性保留了上一个节点的长度,即1或5个字节长度。当电流节点的长度低于254时,请使用一个字节节省其长度。当长度高于254时,使用5使用5或以上。保留单个字节的长度,项目如下:在Ziplist中,节点E1,E2 ... EN,长度为250--253是不断保存的。在此时间之前,将点插入超过254的长度,第二个节点需要修改其自身属性,添加4个字节,并根据此将其推开,直到执行每个节点以执行类似的操作为止。我们命名以下情况:链更新操作逻辑在源代码方法中实现。源代码分析如下:
基于源代码,如下所示。在链条更新的最坏情况下,第二个空间需要重新分配,每个空间分布的最坏复杂性是,链条更新的最坏复杂性是非常危险的,尽管存在,但实现相对苛刻实际使用中最糟糕的条件,并满足与中间之间之间的所有节点之间的长度,在实际情况下,更新的节点仍在很小的区域内,并且不会显而易见可见对性能的影响。
此类操作可以应用于PHP7的源代码。PHP7使用链接列表来处理哈希冲突。同时,开源算法用于计算哈希值。当我们使用恶意数据结构的数据结构的数据结构时,我们可以轻松地获得这种入侵:
执行结果如下:
但是,我们仍然使用PHP大规模实施Web服务,但是我们需要注意防止此类攻击。
在本文中,我们分析了Redis Ziplist的源代码。您可以看到Ziplist的基本记忆结构是一个字节数组。记忆的使用,总体实现几乎不浪费任何可存储的字节,也反映了作者对设计内存型数据库的最终追求。亲自攻击Ziplist,我个人来攻击Ziplist,我个人认为有必要专注于其代码的实施规则以及这些规则背后的意义。同时,我们还对基于此规则高度复杂的操作进行了详细的分析,我们还进行了详细的分析,与PHP源代码相比,三种类型的实现。在时间上使用时间也是许多杰出作品的共同选择。同时,它可以使逻辑严格设计和实现。
原始:https://juejin.cn/post/709785601376191518