首页/数据/Redis 进阶速查/装载因子与扩容时机
内存与管理99 条

装载因子与扩容时机

字典在装载因子超过阈值(约 1,且允许后台保存时放宽到 5)时触发扩容,扩容倍数按需翻倍,理解后可预判内存台阶。

Redis 进阶速查数据更新于 2026-10-13

装载因子与扩容是什么

Redis 的键空间是一个字典(哈希表),装载因子就是「已用元素数 ÷ 桶数量」。装载因子超过约 1 时字典会扩容:新桶数取不小于元素数两倍的最小 2 的幂,然后通过渐进式 rehash 把旧表逐个桶搬到新表。若此时正在做 RDB 保存或 AOF 重写,阈值会放宽到约 5,避免 fork 期间内存翻倍叠加写时复制。

基本信息

常规扩容阈值装载因子约 1
保存/重写期间放宽到约 5 才强制扩容
扩容幅度按元素数翻倍并向上取 2 的幂
缩容阈值装载因子低于约 10% 时由定时任务触发
迁移方式渐进式 rehash,期间新旧两张表共存
观察手段DBSIZE 配合 INFO memory

典型使用场景

  • 预判内存台阶:知道扩容是按倍数的,容量规划就不会用线性模型
  • 解释内存涨而键数没涨:rehash 期间新旧表共存,内存会短时抬高
  • 避免水位边缘批量写入:扩容叠加 rehash 时最容易被淘汰规则砍数据
  • 评估键设计:键多值小时桶指针开销占比升高,用 hash 分桶可以压缩
  • 观察删除后的归还:大量删除不会立刻降内存,缩容是延后且渐进的

最小示例

最小示例
redis-cli DBSIZE                                    # 当前键数量
redis-cli INFO memory | grep used_memory_human      # 当前已用内存
redis-cli INFO memory | grep used_memory_peak_human # 峰值,能看到扩容带来的台阶
redis-cli INFO stats | grep -E 'evicted_keys|expired_keys'  # 是否发生过淘汰
redis-cli --bigkeys                                 # 抽样看键的分布形态

扩容相关现象

现象原因应对
键数翻倍时内存跳台阶桶表按 2 的幂扩容容量按台阶估算,不要用线性外推
内存短时接近原来的两倍rehash 期间新旧两张表共存避开在水位边缘做大批量写入
大量删除后内存不下降缩容阈值低且由定时任务执行看趋势即可,短期不降属正常
大批量导入时突然触发淘汰扩容叠加批量写入推高内存分批导入并预留余量
桶本身就是开销:每个桶一个指针,元素很少、键极多时,桶表占用可以与数据本身同量级,这也是小对象多的场景更适合 hash 分桶的原因。
保存期间把阈值放宽到 5,是为了让扩容尽量避开 fork 窗口;所以持久化期间内存更容易陡增,这段窗口内的占用要单独留余量。

易错点

  • 按线性模型预测内存增长:字典按 2 的幂扩容,实际是台阶式上升,会严重低估峰值
  • 把内存水位卡在临界值:扩容与 rehash 期间需求放大,容易触发淘汰甚至写入失败
  • 把 rehash 期间的内存上涨当泄漏:新旧两张表共存属正常,迁移完成后会回落
  • 忽略桶与键名的开销:键多值小时桶指针与键名可能比数据更吃内存,考虑用 hash 分桶
  • 大量删除后立刻要求内存归还:缩容由定时任务按低装载因子触发,短期不降是预期行为

数据来源与参考

  • Redis 官方文档:哈希表扩容策略
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌