参考:<<Redis设计与实现>>
- 注:这本书是基于Redis3.0版本写的,和后面的版本有点差异
哈希对象的编码是:
- ziplist
- hashtable
一、哈希对象的编码
1.1 ziplist编码
ziplist编码的哈希对象使用压缩列表作为底层实现,当有新的键值对要加入哈希对象时,程序会先将保存了键的压缩列表推入到压缩列表表尾,然后再将保存了值的压缩列表节点推入到压缩列表表尾。
- 保存了同一键值对的两个节点总是紧挨在一起,保存键的节点在前,保存值的节点在后
- 先添加到哈希对象中的键值对会被放在压缩列表的表头方面,后来添加到哈希对象中的键值对会被放在压缩列表的表尾方向
示例:
插入数据:
redis> hmset profile name "Tom" age 25 career "Programmer"
OK
如果profile键的值对象使用的是ziplist编码,那么值对象、以及值对象使用的压缩列表如下图所示:
1.2 hashtable编码
hashtable编码的哈希对象使用字典作为底层实现,哈希对象中的每个键值对都使用一个字典键值对来保存:
- 字典的每个键都是一个字符串对象,对象中保存了键值对的键
- 字典的每个值都是一个字符串对象,对象中保存了键值对的值
如果上面示例中的profile使用的是hashtable编码,那么profile使用的hashtable如下图所示:
二、编码的转换
当哈希对象同时满足以下两个条件时,使用ziplist编码,否则使用hashtable编码:
- 所有键值对的键和值的字符串长度都小于64字节
- 键值对数量小于512个
注:64、512这个阈值可以配置,可以查看hash-max-ziplist-value
、hash-max-ziplist-entries
两个选项。
2.1 ziplist -> hashtable
当两个条件任意一个不满足时,就会执行对象的编码转换操作,原本保存在压缩列表里的所有键值对都会被转移并保存到字典里,对象的编码会从ziplist变为hashtable。
(1)键或值长度超过阈值
临时设置hash-max-ziplist-value
值为4
redis> config set hash-max-ziplist-value 4
OK
redis> hmset strs one a two aa four aaaa
OK
redis> object encoding strs
"ziplist"
redis> hset strs five aaaaa
(integer) 1
redis> object encoding strs
"hashtable"
(2)键值对数量超过阈值
临时设置hash-max-ziplist-entries
值为4
redis> config set hash-max-ziplist-entries 4
OK
redis> hmset strs one a two aa three aaa four aaaa
OK
redis> object encoding strs
"ziplist"
redis> hset strs five aaaaa
(integer) 1
redis> object encoding strs
"hashtable"