Redis 的哈希表实现采用了开放寻址法中的线性探测(linear probing)来解决哈希冲突。当插入一个新元素时,如果计算出的哈希值对应的槽位已经被其他元素占用,Redis 会按照一定的规则寻找下一个可用的槽位。这个过程就称为 rehash。
以下是 Redis rehash 机制的详细工作原理:
-
初始化阶段:
- 当 Redis 创建一个新的哈希表时,它首先会分配一个初始大小(例如 64 个槽位)。
- 接着,Redis 会使用一个哈希函数(如 CRC16)来计算每个键的哈希值,并根据这个哈希值将键值对存储到对应的槽位中。
-
rehash 触发:
- 当哈希表中的元素数量达到一定阈值(例如,当前槽位数量的 75%)时,Redis 会触发 rehash 操作。这个阈值可以通过配置参数
hash_max_ziplist_entries
和hash_max_ziplist_value
来调整。 - 另外,当执行某些命令(如
HSET
、HGET
、HDEL
等)导致哈希表中的元素数量发生变化时,也可能触发 rehash 操作。
- 当哈希表中的元素数量达到一定阈值(例如,当前槽位数量的 75%)时,Redis 会触发 rehash 操作。这个阈值可以通过配置参数
-
执行 rehash:
- 在触发 rehash 之后,Redis 会创建一个新的哈希表,其大小通常是当前哈希表的两倍(具体大小可以通过配置参数
hash_table_max_size
来调整)。 - 接着,Redis 会遍历旧哈希表中的所有键值对,并使用新的哈希函数计算每个键的哈希值。根据新的哈希值,Redis 会将键值对存储到新的哈希表中的相应槽位。
- 在触发 rehash 之后,Redis 会创建一个新的哈希表,其大小通常是当前哈希表的两倍(具体大小可以通过配置参数
-
完成 rehash:
- 当所有键值对都从旧哈希表迁移到新哈希表之后,Redis 会更新内部指针,使其指向新的哈希表。
- 最后,Redis 会释放旧哈希表的内存空间,以便在必要时可以用于创建更大的哈希表。
需要注意的是,Redis 的 rehash 机制是自动进行的,用户无需手动触发。此外,Redis 还支持在运行时动态地调整哈希表的大小,以适应不断变化的数据量和负载。