1. 是什么
Redis Hash(散列表)是一种 field-value pairs(键值对)集合类型,类似于 Python 中的字典、Java 中的 HashMap。一个 field 对应一个 value,你可以通过 field 在 O(1) 时间复杂度查 field 找关联的 field,也可以通过 field 来更新或者删除这个键值对。
Redis 的散列表 dict 由数组 + 链表构成,数组的每个元素占用的槽位叫做哈希桶,当出现散列冲突的时候就会在这个桶下挂一个链表,用“拉链法”解决散列冲突的问题。
简单地说就是将一个 key 经过散列计算均匀的映射到散列表上。
图 2-18
图 2-18
2. 修炼心法
Hash 数据类型底层存储数据结构实际上有两种。
-
dict 结构。
-
在 7.0 版本之前使用 ziplist,之后被 listpack 代替。
通常情况下使用 dict 数据结构存储数据,每个 field-value pairs
构成一个 dictEntry 节点来保存。
只有同时满足以下两个条件的时候,才会使用 listpack(7.0 版本之前使用 ziplist)数据结构来代替 dict 存储, 把 key-value 键值对按照 field 在前 value 在后,紧密相连的方式放到一次把每个键值对放到列表的表尾。
-
每个键值对中的 field 和 value 的字符串字节大小都小于
hash-max-listpack-value
配置的值(默认 64)。 -
field-value pairs 键值对数量小于
hash-max-listpack-entries
配置的值(默认 512)。
每次向散列表写数据的时候,都会调用 t_hash.c
中的hashTypeConvertListpack()
函数来判断是否需要转换底层数据结构。
当插入和修改的数据不满足以上两个条件时,就把散列表底层存储结构转换成 dict
结构。需要注意的是