Redis哈希表的渐进式rehash是如何实现的?

Redis 渐进式 rehash(重哈希)的核心是 分批次、穿插在日常操作中迁移数据,通过维护关键状态变量和双表并行机制,实现非阻塞的数据迁移,具体实现逻辑如下:

1. 核心状态变量

Redis 字典(dict 结构)中维护 3 个关键变量,用于控制 rehash 过程:

  • rehashidx:标记当前 rehash 进度的索引,初始值为 -1(表示未进行 rehash);开始 rehash 后设为 0,每迁移完一个哈希桶就加 1,直到等于原表容量(迁移完成)。

  • ht[0]:原哈希表(旧表),rehash 前存储所有数据,迁移过程中逐步清空。

  • ht[1]:新哈希表(新表),rehash 开始时创建,容量根据扩容/缩容规则确定,用于接收迁移的数据。

2. 具体实现步骤

步骤 1:初始化新表与 rehash 状态

当负载因子触发扩容(>1)或缩容(<0.1)时:

1.根据规则计算 ht[1] 的容量(扩容为 ht[0] 的 2 倍,缩容为大于当前 size 的最小 2 的幂)。

2.为 ht[1] 分配内存,初始化所有哈希桶为空。

3.将字典的 rehashidx 设为 0,标志 rehash 正式开始。

步骤 2:分批次迁移数据(核心逻辑)

rehash 不一次性迁移所有数据,而是 穿插在字典的每一次增删改查操作中,每次迁移 1 个哈希桶(ht[0] 中 rehashidx 指向的桶),具体逻辑:

1.当客户端对字典执行 查询、删除、更新 操作时:

先处理当前操作(如查询时,先查 ht[1] 再查 ht[0],确保数据不遗漏)。

检查 rehashidx 是否不为 -1(即正在 rehash),若是则执行 一次迁移:将 ht[0] 中 rehashidx 指向的哈希桶内所有键值对,重新计算哈希值后迁移到 ht[1] 对应的桶中。

迁移完成后,rehashidx 加 1,推进迁移进度。

2.额外「主动迁移」:为避免 rehash 长期停滞(如字典长时间无操作),Redis 还会在 定时任务(serverCron) 中,批量迁移多个哈希桶(默认一次迁移 100 个桶),加速进度。

步骤 3:读写操作适配双表

rehash 期间,ht[0] 和 ht[1] 同时存在,所有操作需适配双表,确保数据正确性:

写入操作(新增键值对):只写入 ht[1],不写入 ht[0],避免 ht[0] 持续产生新数据,导致迁移无法结束。

查询/删除/更新操作:先在 ht[1] 中查找,若未找到再去 ht[0] 中查找,确保能访问到所有数据。

步骤 4:rehash 完成收尾

当 rehashidx 的值等于 ht[0] 的容量时,说明 ht[0] 所有哈希桶已迁移完毕:

1.释放 ht[0] 的内存空间。

2.将 ht[1] 赋值给 ht[0](新表成为主表)。

3.清空 ht[1](重置为空表,供下次 rehash 使用)。

4.将 rehashidx 设回 -1,标志 rehash 结束。

核心优势

  • 非阻塞:避免一次性迁移大量数据导致主线程阻塞,保障 Redis 高并发响应能力。

  • 低开销:迁移操作分散在日常请求中,单次迁移成本极低,对服务性能影响可忽略。

Redis渐进式rehash是一种在进行哈希表扩容或收缩时的一种渐进式处理方式。它避免了Redis阻塞的问题,但也带来了一些其他的问题。在进行渐进式rehash时,Redis需要分配一个新的哈希表,并为该哈希表分配新的大小的内存。这导致了Redis内存使用量瞬间增加,并且在Redis满容状态下,rehash操作会导致大量的Key被驱逐。 为了解决这个问题,Redis实现了辅助服务器来在读写操作时进行渐进式rehash操作。但是如果服务器比较空闲,Redis数据库将会长时间同时使用两个哈希表。为了处理这种情况,Redis周期函数在发现字典正在进行渐进式rehash操作时,会花费1毫秒的时间来帮助进行渐进式rehash操作。 总之,Redis渐进式rehash是一种有效避免阻塞的哈希表扩容或收缩方式,但在操作过程中可能会导致内存使用量增加和大量Key被驱逐的问题。为了处理这些问题,Redis使用辅助服务器和周期函数来优化渐进式rehash操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Redis详解(六)渐进式rehash机制](https://blog.csdn.net/fedorafrog/article/details/104633237)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值