内容来自:
《redis设计与实现》购买本书请访问: 京东商城
《Redis 深度历险:核心原理与应用实践》购买本书请访问: 京东商城
redis哈希对象
哈希对象的编码可以是 ziplist
或者 hashtable
ziplist
ziplist
编码的哈希对象使用压缩列表作为底层实现, 每当有新的键值对要加入到哈希对象时, 程序会先将保存了键的压缩列表节点推入到压缩列表表尾, 然后再将保存了值的压缩列表节点推入到压缩列表表尾。如:
redis> HSET profile name "Tom"
(integer) 1
redis> HSET profile age 25
(integer) 1
redis> HSET profile career "Programmer"
(integer) 1


hashtable
如果是hashtable
编码,则如下图所示:

-
编码转换
当哈希对象可以同时满足以下两个条件时, 哈希对象使用
ziplist
编码:-
哈希对象保存的所有键值对的键和值的字符串长度都小于
64
字节; -
哈希对象保存的键值对数量小于
512
个;
以上两个条件的上限值是可以修改的, 具体请看配置文件中关于
hash-max-ziplist-value
选项和hash-max-ziplist-entries
选项的说明 -
-
哈希部分命令实现
命令 ziplist
编码实现方法hashtable
编码的实现方法HSET 首先调用 ziplistPush
函数, 将键推入到压缩列表的表尾, 然后再次调用ziplistPush
函数, 将值推入到压缩列表的表尾。调用 dictAdd
函数, 将新节点添加到字典里面。HGET 首先调用 ziplistFind
函数, 在压缩列表中查找指定键所对应的节点, 然后调用ziplistNext
函数, 将指针移动到键节点旁边的值节点, 最后返回值节点。调用 dictFind
函数, 在字典中查找给定键, 然后调用dictGetVal
函数, 返回该键所对应的值。HEXISTS 调用 ziplistFind
函数, 在压缩列表中查找指定键所对应的节点, 如果找到的话说明键值对存在, 没找到的话就说明键值对不存在。调用 dictFind
函数, 在字典中查找给定键, 如果找到的话说明键值对存在, 没找到的话就说明键值对不存在。HDEL 调用 ziplistFind
函数, 在压缩列表中查找指定键所对应的节点, 然后将相应的键节点、 以及键节点旁边的值节点都删除掉。调用 dictDelete
函数, 将指定键所对应的键值对从字典中删除掉。HLEN 调用 ziplistLen
函数, 取得压缩列表包含节点的总数量, 将这个数量除以2
, 得出的结果就是压缩列表保存的键值对的数量。调用 dictSize
函数, 返回字典包含的键值对数量, 这个数量就是哈希对象包含的键值对数量。HGETALL 遍历整个压缩列表, 用 ziplistGet
函数返回所有键和值(都是节点)。遍历整个字典, 用 dictGetKey
函数返回字典的键, 用dictGetVal
函数返回字典的值。
网友评论