Redis中hash对象是一个string类型的field和value的映射表,hash特别适合用于存储对象。作为哈希对象的编码,有二种一是ziplist编码, 二是hashtable编码。在不同情况下编码是可以转换的。在Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)。
Hash结构与Redis中的Zset非常类似:
区别
因此,Hash底层采用的编码与Zset也基本一致,只需要把排序有关的SkipList去掉。
哈希对象的编码可以是
ziplist
或者hashtable
。
ziplist
编码的哈希对象使用压缩列表作为底层实现, 每当有新的键值对要加入到哈希对象时, 程序会先将保存了键的压缩列表节点推入到压缩列表表尾, 然后再将保存了值的压缩列表节点推入到压缩列表表尾, 因此:
如果我们执行以下 HSET 命令, 那么服务器将创建一个列表对象作为 profile
键的值:
redis> HSET profile name "Tom"
(integer) 1redis> HSET profile age 25
(integer) 1redis> HSET profile career "Programmer"
(integer) 1
如果 profile
键的值对象使用的是 ziplist
编码, 那么这个值对象将会是如图所示。
hashtable
编码的哈希对象使用字典作为底层实现, 哈希对象中的每个键值对都使用一个字典键值对来保存:
举个例子, 如果前面 profile
键创建的不是 ziplist
编码的哈希对象, 而是 hashtable
编码的哈希对象。
Hash结构默认采用ZipList编码,用以节省内存。 ZipList中相邻的两个entry 分别保存field和value
当数据量较大时,Hash结构会转为HT编码,也就是Dict,触发条件有两个:
(1)哈希对象保存的所有键值对的键和值的字符串长度都小于64字节;
(2) 哈希对象保存的键值对数量小于512个。
当不能满足这两个条件的哈希对象需要使用hashtable编码。
对于上面编码转换的两个条件,上限值是可以修改的,具体看配置文件中关于hash-max-ziplist-value选项和hash-max-ziplist-entries选项说明。
127.0.0.1:6379> config get hash-max-ziplist-value1) "hash-max-ziplist-value"2) "64"127.0.0.1:6379> config get hash-max-ziplist-entries1) "hash-max-ziplist-entries"2) "512"
参考
《Redis 设计与实现》
黑马程序员