在 Redis 中,rehash 是一种维护哈希表性能的重要机制,主要应用于字典(dictionary)数据结构。当 Redis 中的字典存储的键值对数量增加,导致负载因子(已存储键值对数量/哈希表大小)达到一定程度时,Redis 会启动 rehash 过程来扩展哈希表,防止因哈希冲突增多而导致查找效率下降。
以下是 Redis 实战中 rehash 的详细步骤:
-
检测与启动 Rehash:
Redis 会持续监控字典的负载因子,当负载因子超过预设阈值(通常为 1),系统会启动 rehash 过程。 -
分配新哈希表:
Redis 会创建一个新的、容量更大的哈希表ht[1]
,容量通常是现有哈希表ht[0]
的两倍左右。 -
渐进式 Rehash:
Redis 采用的是渐进式 rehash 策略,而不是一次性将所有键值对从旧表移动到新表。具体实施如下:- 设置一个 rehash 索引计数器
rehashidx
,初始值设为 0。 - 在后续执行字典的添加、删除、查找或更新操作时,除了正常执行相应操作之外,还会检查
rehashidx
是否小于旧哈希表ht[0]
的大小。 - 若满足条件,则将
ht[0]
在rehashidx
索引处的所有键值对 rehash 到ht[1]
中,然后递增rehashidx
。 - 如此反复,每次操作都会推进 rehash 进程一点点,直至
rehashidx
达到ht[0]
的大小,表明 rehash 完成。
- 设置一个 rehash 索引计数器
-
切换哈希表:
当 rehash 过程完成后,Redis 会将旧的哈希表ht[0]
替换掉(可能释放其空间),并将新表ht[1]
设为新的ht[0]
,然后准备下一轮可能的 rehash。
通过渐进式 rehash,Redis 有效地分散了 rehash 所带来的 CPU 和内存操作的压力,避免了在某一瞬间阻塞服务的可能性,确保了数据库的高性能运行。