【Redis】深入理解 Redis 常用数据类型源码及底层实现(4.详解Hash数据结构)

Hash数据结构

看过前面的介绍,大家应该知道 Redis 的 Hash 结构的底层实现在 6 和 7 是不同的,Redis 6 是 ziplist 和 hashtable,Redis 7 是 listpack 和 hashtable。

我们先使用config get hash*看下 Redis 6 和 Redis 7 的 Hash 结构配置情况(在Redis客户端的命令行界面中使用INFO server可以查看包括版本号等各个信息)

【Redis】深入理解 Redis 常用数据类型源码及底层实现(4.详解Hash数据结构)_第1张图片

通过Docker拉取一个Redis7的镜像,同样的命令查看相关信息

【Redis】深入理解 Redis 常用数据类型源码及底层实现(4.详解Hash数据结构)_第2张图片

【Redis】深入理解 Redis 常用数据类型源码及底层实现(4.详解Hash数据结构)_第3张图片

可以看到Redis7多了hash-max-listpack-entries和hash-max-listpack-value两项,我们先介绍下这四个参数的含义:

  • hash-max-ziplist-entries:使用压缩列表保存数据时,哈希集合中最大的元素个数
  • hash-max-ziplist-value:使用压缩列表保存数据时,哈希集合中单个元素的最大长度
    • 单位byte:一个英文字母一个byte
  • hash-max-listpack-entries:使用紧凑列表保存数据时,哈希集合中最大的元素个数
  • hash-max-listpack-value:使用紧凑列表保存数据时,哈希集合中单个元素的最大长度

上面两张图中的参数都是默认情况,为了方便测试效果我们把这两个值都改小些(如下图)

【Redis】深入理解 Redis 常用数据类型源码及底层实现(4.详解Hash数据结构)_第4张图片

依次存储不同长度的值,并查看编码方式

【Redis】深入理解 Redis 常用数据类型源码及底层实现(4.详解Hash数据结构)_第5张图片

【Redis】深入理解 Redis 常用数据类型源码及底层实现(4.详解Hash数据结构)_第6张图片

有上面两张图可以看到,当同时满足字段个数小于hash-max-ziplist-entries并且字段值都小于hash-max-ziplist-value时,才会使用OBJ_ENCODING_ZIPLIST的编码方式进行存储,二者不满足任意一个就会转换为OBJ_ENCODING_HT的编码方式进行存储,并且不可逆(OBJ_ENCODING_ZIPLIST变成OBJ_ENCODING_HT可以,但是即便存储的数据又满足了上面提到的两个要求,OBJ_ENCODING_HT也不会再变回OBJ_ENCODING_ZIPLIST(反反复复浪费性能),相比较OBJ_ENCODING_HT,OBJ_ENCODING_ZIPLIST会更节省内存空间)。

源码分析

t_hash.c

hashtable在Redis中被称为“字典”,他是一个数组+链表的结构

OBJ_ENCODING_HT这种编码方式内部才是真正的哈希表结构,或称为字典结构,有一个dictEntry,详见下图源代码:

【Redis】深入理解 Redis 常用数据类型源码及底层实现(4.详解Hash数据结构)_第7张图片

OBJ_ENCODING_HT这种编码方式内部才是真正的哈希结构(或称为字典结构),其可以实现O(1)的时间复杂度的读写操作,因此效率很高,在Redis内部,从OBJ_ENCODING_HT类型到底层真正的散列表数据结构是一层一层嵌套起来的,组织关系如

你可能感兴趣的:(Redis,Redis,中间件,Hash,数据结构,源码分析)