Redis是一款著名的key-value内存数据库软件,同时也是一款卓越的数据结构服务软件。它支持字符串、列表、哈希表、集合、有序集合五种数据结构类型,同时每种数据结构类型针对不同的应用场景又支持不同的编码方式。
redis数据结构之压缩列表
redis使用压缩列表作为列表键和哈希键的底层实现之一。当一个列表键只包含少量的列表项,并且每个列表项都是由小整数值或者是短字符串组成,那么redis就会使用压缩列表存储列表项;同理,当一个哈希表包含的键值对都是由小整数值或者是短字符串组成,并且存储的键值对数目不多时,redis也会使用压缩列表来存储哈希表。以下是压缩列表存储结构:
常态的压缩列表内存编码如上图所示,整个内存块区域内分为五个部分,下面分别介绍着五个部分:
zlbytes长度为4个字节,记录了整个压缩列表所占用的字节数
zltail长度为4个字节,记录了压缩列表起始位置到压缩列表尾节点的偏移量
zllen长度为2个字节,记录了当前压缩列表中所拥有的entry的数量
entryX存储了实际的对象,其长度根据具体的实体而定
zlend长度为1个字节,保存了十进制的255,用于标记压缩列表的末端
通过上面的结构可以看出,压缩列表存储数据的为一整个数组,在这个数组中前12个字节固定保存了zlbytes、zltail和zllen三个表征整个压缩列表属性的数据,而后续的数组则保存了entry的数组,最后通过一个字节长度的属性zlend来记录当前压缩列表已经结束。
列表元素编码
上面介绍了压缩列表的总体内存布局,对于初entryX区域以外的四个区域的长度都是固定的,下面再看看entryX区域的编码情况。
在上述结构中,我们并没有看到任何属性用以表征每个entry的长度及其存储的数据类型,如字符串或者是整型值,而压缩列表整体其实是一个数组,因而如果不对这两个类型的数据进行记录那么将无法对每一个entry进行区分。实际上,每个entry是由三部分组成:previous_entry_length、encoding和content。
每个压缩列表节点区域头部包含两部分,一部分叫做previouslength,另一部分叫encoding,最后是主体内容,叫做content,下面分别介绍他们:
previous length
用于存储上一个节点的长度,因此压缩列表可以从尾部向头部遍历,即当前节点位置减去上一个节点的长度即得到上一个节点的起始位置。previouslength的长度可能是1个字节或者是5个字节,如果上一个节点的长度小于254,则该节点只需要一个字节就可以表示前一个节点的长度了,如果前一个节点的长度大于等于254,则previouslength的第一个字节为254,后面用四个字节表示当前节点前一个节点的长度。这么做很有效地减少了内存的浪费。
encoding
节点的encoding保存的是节点的content的内容类型以及长度,encoding类型一共有两种,一种字节数组一种是整数,encoding区域长度为1字节、2字节或者5字节长。Redis作者巧妙的利用了前两个字节来表示content存储的内容类型和encoding区域的长度,我们先看看字节数组类型的encoding内容:
再看看整数编码类型的encoding内容:
content
content区域用于保存节点的内容,节点内容类型和长度由encoding决定,上面可以看出目前content的内容类型有整数类型和字节数组类型,且某些条件下content的长度可能为0。
相信到这里,我们都明白了压缩列表的原理,压缩列表并不是对数据利用某种算法进行压缩,而是将数据按照一定规则编码在一块连续的内存区域,目的是节省内存。
小编结语:
更多内容尽在课课家教育!
下一篇:oracle数据类型详解
¥29.90
¥798.00
¥199.00
¥48.00¥180.00
¥199.00
¥48.00¥180.00