《Redis设计与实现》读书笔记(八) ——Redis列表对象和哈希对象实现原理
(原创内容,转载请注明来源,谢谢)
一、列表对象
列表对象的编码可以是ziplist(压缩列表)或者linkedlist(双端链表)。
1、ziplist
ziplist底层是压缩列表的方式实现,每个压缩列表节点(entry)保存一个列表元素。如下图所示:
2、linkedlist
linkedlist底层是用双端链表的方式实现,每个双端链表的节点(node)都保存了一个字符串对象,而对象里面保存的是列表的元素。这个方式与ziplist不同。如下图所示:
上图中,StringObject是字符串对象的简化表示,实际上的方式如下(字符串对象three的实际方式):
字符串对象被嵌套在其他对象中,这种情况只有字符串对象会发生,其他四种对象都不允许嵌套在其他对象中。
3、编码使用条件
由于在数据量少的情况下,ziplist效率更高,但是数据量大的时候性能不如linkedlist。因此,当对象同时满足下列两种条件时,会使用ziplist保存列表对象的元素:
1)列表对象中的所有字符串元素长度都小于64字节。64字节这个数目,是在redis配置文件中,list-max-ziplist-value选项确定的,默认值是64字节。
2)列表对象保存的字符串元素个数少于512个。512个元素这个数目,是在redis配置文件中,list-max-ziplist-entries选项确定的,默认值是512个。
上述任一个条件不满足,则会使用linkedlist方式进行编码。
如果一开始是使用ziplist对列表进行编码,而使用过程中节点数目或节点元素长度超过设定使用ziplist的条件,则redis会将其转换成linkedlist的方式进行编码。
4、列表命令执行的条件
二、哈希对象
哈希对象底层编码方式是ziplist或hashtable。
1、ziplist
ziplist实现哈希对象时,是先将键节点压缩进列表,再将值节点压缩进列表。因此ziplist保存哈希对象时,键和值是挨着的。且先添加的哈希对象会在表头,后添加的在表尾。
总体结构如下图所示:
具体的压缩列表如下图所示:
2、hashtable
hashtable实现哈希对象时,每个键值对都用一个字典来保存,且键和值都是字符串对象,分别对应哈希对象中的键和值。
如下图所示:
3、编码使用条件
由于在数据量少的情况下,ziplist效率更高,但是数据量大的时候性能不如hashtable。因此,当对象同时满足下列两种条件时,会使用ziplist保存列表对象的元素:
1)哈希对象中的所有键值对的键和值长度都小于64字节。64字节这个数目,是在redis配置文件中,hash-max-ziplist-value选项确定的,默认值是64字节。
2)哈希对象保存的键值对总数少于512个。512个元素这个数目,是在redis配置文件中,hash-max-ziplist-entries选项确定的,默认值是512个。
上述两个要求和列表中使用ziplist的条件相似,除了配置文件中的配置内容是以hash开头(列表是以list开头)。
4、哈希命令执行条件
——written by linhxx 2017.09.01