持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情
\
基本概念
哈希,不仅是redis对外提供的5种对象类型的一种,也是Redis作为Key-Value数据库所使用的数据结构。为了说明的方便,在本文后面当使用“内层的哈希”时,代表的是redis对外提供的5种对象类型的一种;使用“外层的哈希”代指Redis作为Key-Value数据库所使用的数据结构。
内部编码
哈希对象的编码可以是 压缩列表(ziplist) 或者字典(hashtable)。
ziplist:
ziplist编码的哈希对象使用压缩列表作为底层实现,每当有新的键值对要加入到哈希对象时,程序会先将保存了键的压缩列表节点推入到压缩列表表尾,然后再将保存了值的压缩列表节点推人到压缩列表表尾
- 保存了同一键值对的两个节点总是紧挨在一起,保存键的节点在前,保存值的节点在后
- 先添加到哈希对象中的键值对会被放在压缩列表的表头方向,而后来添加到哈希对象中的键值对会被放在压缩列表的表尾方向
- 当使用ziplist,也就是压缩列表作为底层实现时,新增的键值对是保存到压缩列表的表尾。
hashtable:
一个hashtable由1个dict结构、2个dictht结构、1个dictEntry指针数组(称为bucket)和多个dictEntry结构组成。
- 字典的每个键都是-一个字符串对象,对象中保存了键值对的键
- 字典的每个值都是-一个字符串对象,对象中保存了键值对的值
编码转换
-
Redis中内层的哈希既可能使用哈希表,也可能使用压缩列表。
-
只有同时满足下面两个条件时,才会使用压缩列表。(1)哈希中元素数量小于512个(2)哈希中所有键值对的键和值字符串长度都小于64字节。
-
不能满足这两个条件的哈希对象需要使用hashtable编码。第一个条件可以通过配置文件中的 set-max-intset-entries 进行修改
-
编码只可能由压缩列表转化为哈希表,反方向则不可以。