Sunday面试指南

Redis 渐进式 rehash 是什么?扩容时为什么还能继续处理请求?

下面是一段教学用的模拟面试。

🧑‍💻 面试官:哈希表扩容,要把所有键搬到新表。Redis 怎么避免一次搬完?

🙋‍♂️ 我:它会开一个后台线程迁移,所以主线程不会受影响。

🧑‍💻 面试官:渐进式 rehash 一定由独立线程完成吗?迁移中查一个键,要查哪张表?

🙋‍♂️ 我:新旧表都要兼顾。

🧑‍💻 面试官:新键放哪里?如果一个桶里有很多键,单次迁移能保证毫无延迟吗?

渐进式的重点是把迁移工作拆开,不是把工作变没,也不是自动搬到另一条线程。

面试速答(60 秒版)

Redis 字典进行渐进式 rehash 时,会暂时维护新旧两张哈希表,把旧表的键分批迁移到新表。

迁移期间,新插入通常进入新表,查找和删除则需要按迁移状态兼顾两张表,保证尚未搬走的键仍然可用。

字典操作和受时间预算约束的周期工作可以推动迁移,不必一次处理全部数据。迁移完成后,释放旧表并让新表接替。

这样能分摊长时间阻塞,但不是零成本:迁移期多一张表,占用内存和 CPU,单个桶的工作量也可能不同。具体触发条件与实现细节应按 Redis 版本核对。

Redis渐进式rehash期间新旧哈希表协同工作

知识点详解:一边使用字典,一边把旧表搬空

为什么扩容不能只增加几个空桶?

键所在的桶与表大小有关。表的桶数量改变后,很多键应当位于新的位置,不是把新桶追加上去就结束。

假设旧表有四个桶,新表有八个桶。某个键原来落在旧桶 1,重新计算后可能进入新桶 5。新桶位置要按新的规则计算,不能简单照搬旧桶编号。

这里讨论 Redis 的字典哈希表,不是在说每一种 Redis 数据结构都采用同样的扩容过程。

新旧两张表怎样共同工作?

迁移开始时,旧表仍保存原来的键,新表准备接收迁移数据。Redis 记录迁移进度,逐步搬空旧表。

假设键 A 已经迁移,键 B 还在旧表,新键 C 刚插入。A 在新表,B 在旧表,C 通常进入新表。

查询 B 时,不能只看新表;修改或删除也必须找到键实际所在的位置。因为这些操作与迁移状态配合,用户不需要等所有键搬完才能继续访问。

当旧表已经没有需要迁移的键,新表接替旧表的位置,原旧表资源才能释放。

谁在推动迁移?

按本次核对的 Redis 8.2 字典源码,常见字典操作会帮助执行迁移步骤,源码也提供受时间预算约束的迁移入口。Redis 8.2 dict.c

这说明“渐进式”描述的是工作如何分摊,而不是单凭名字就能推断它发生在后台线程。

迁移的具体策略、暂停条件与周期调用还涉及更外层实现。不应把某个版本中的固定步数或触发阈值,当作所有版本永远不变的规则。

一步迁移,为什么不一定只搬一个键?

桶中可能保存一串冲突键。按桶推进迁移时,一次步骤可能处理该桶中的多个键;空桶扫描同样需要限制工作量。

因此可以说避免一次搬完整个表,但不能承诺“每条请求都只增加一个固定纳秒成本”,也不能保证扩容期间完全没有尾延迟变化。

新旧表并存还会增加一段时间的内存占用。渐进式换来了较平滑的工作安排,却没有免除扩容本身的资源成本。

如何观察,而不是只背搬家过程?

在可控环境里准备逐渐增长的数据,记录内存、CPU、吞吐与延迟分布。关注高分位延迟,而不是只看平均值。

同时区分字典扩容、淘汰、持久化和大键操作等其他因素。一次延迟升高恰好出现在内存增长期间,不足以证明原因只有 rehash。

面试官继续追问

渐进式 rehash 和一致性哈希是一回事吗?

不是。这里是在单个字典的新旧表之间迁移键,一致性哈希通常讨论键如何映射到不同节点或分片。

新旧表各保存一份完整数据吗?

不是。迁移中的键分布在两表中,已经搬走的旧位置会被清理。不要理解成整份数据长期双写备份。

为什么不直接一次搬完?

小表一次迁移可能成本不高,但大表集中迁移会占用较长执行时间。分批的价值主要在于控制单次工作对响应的影响。

面试速记卡

  • 渐进式:分批迁移,不等于独立线程或零成本。
  • 迁移状态:新旧表并存,操作必须兼顾键所在位置。
  • 新键:通常进入新表,完成后由新表接替。
  • 工作粒度:一个桶可能包含多个键。
  • 工程观察:内存、CPU 与尾延迟,具体细节按版本核对。

公司面试真题

真题根据求职者公开面经整理,题意经过概括,非逐字原话或公司官方题库;本文为 Sunday 的独立解析。

浏览公司面试真题 →
简历汪永久免费在线制作简历,模板直接套用、导出无水印,永久免费、下载免费,不需要付费解锁任何功能。去写简历