当前位置: 首页 > news >正文

Redis哈希表渐进式Rehash期间的读写机制深度剖析



1. 重写的核心目的


AOF文件记录了所有写命令,随着服务运行时间增长,文件体积会不断膨胀,带来三个问题:


| 问题 | 影响 |

|------|------|

|磁盘空间占用| 日志文件可能比实际数据大数十倍 |

|数据恢复缓慢| Redis重启时需重放海量命令,耗时从分钟级到小时级 |

|网络传输压力| 主从复制时传输大文件占用带宽 |


举例:对同一Key执行100万次INCR,AOF会记录100万条命令。重写后只需一条SET counter 1000000


2. 重写原理:读内存而非读文件


AOF重写的核心思想是读取当前内存数据,生成最小命令集,而不是读取旧的AOF文件进行压缩。


读取内存生成写入

旧AOF文件
100万条命令

当前数据库状态

最小命令集

新AOF文件
1条命令


3. 重写完整流程


新AOF文件重写缓冲区Fork子进程主进程新AOF文件重写缓冲区Fork子进程主进程手动/自动触发BGREWRITEAOF子进程获得内存快照子进程重写完成1. 检查是否已在重写2. fork子进程3. 继续处理客户端请求4. 写命令同时写入aof_buf和重写缓冲区5. 遍历所有DB6. 每个Key生成最小命令7. 写入临时AOF文件8. 通知主进程9. 重写缓冲区内容追加到新AOF10. 原子重命名替换旧AOF11. 清空重写缓冲区


4. 重写触发方式


手动触发

# 手动执行重写 BGREWRITEAOF


自动触发(满足两个条件):

# 条件1: 文件大小超过设定值 auto-aof-rewrite-min-size 64mb # 条件2: 文件比上次重写后增长超过设定百分比 auto-aof-rewrite-percentage 100


// 自动重写检查逻辑(简化) void check_rewrite(void) { // 获取当前AOF大小 long long aof_size = server.aof_current_size; // 条件1: 文件大于最小值 if (aof_size < server.aof_rewrite_min_size) return; // 条件2: 增长率超过百分比 if (aof_size < server.aof_rewrite_base_size * (100 + server.aof_rewrite_percentage) / 100) return; // 触发重写 rewriteAppendOnlyFileBackground(); }


5. 重写期间的写操作处理


重写期间,Redis采用双写策略保证数据不丢失:


写操作

是否正在重写?

写入aof_buf

定期刷盘到AOF文件

写入aof_buf

写入aof_rewrite_buf_blocks

重写完成后追加到新AOF


关键点

  • aof_buf:常规缓冲区,保证正常AOF写入
  • aof_rewrite_buf_blocks:专门用于重写的缓冲区,存储重写期间的所有增量命令
  • 重写完成后,先追加增量命令,再原子替换文件


6. 重写过程中的内存管理


// 重写缓冲区结构 typedef struct aofrwblock { unsigned long used; // 已使用字节数 unsigned long free; // 剩余字节数 char buf[1024 * 10]; // 10KB块 } aofrwblock; // 增量命令以链表形式存储 list *aof_rewrite_buf_blocks; // 多个内存块


内存控制:当重写缓冲区增长过快(超过内存限制),Redis会主动限流:


// 如果重写缓冲区超过内存限制,降低写入速度 if (server.aof_rewrite_buf_blocks_mem > server.aof_rewrite_buf_limit) { // 主动延迟响应,让子进程有时间完成重写 usleep(1000); }


7. 磁盘空间安全策略


重写期间同时存在旧AOF新AOF(临时)两个文件,需确保磁盘空间充足:


# 重写过程中的文件状态 -rw-r--r-- 1 redis redis 10G appendonly.aof # 旧文件 -rw-r--r-- 1 redis redis 2G temp-rewrite.aof # 临时新文件


安全建议

# 配置重写时停止fsync,减少磁盘IO竞争 no-appendfsync-on-rewrite yes # 监控磁盘空间,建议预留30%以上空闲


8. 重写性能影响


| 阶段 | 影响 | 持续时间 |

|------|------|---------|

|fork()| 主线程短暂阻塞(数十ms~数百ms) | 与内存大小成正比 |

|子进程重写| CPU密集型,内存消耗(Copy-on-Write) | 分钟级 |

|文件替换| 原子操作,几乎无影响 | 毫秒级 |


优化建议

  • 业务低峰期(凌晨)手动触发重写
  • 控制单个Redis实例内存 ≤ 16GB(减少fork耗时)
  • 监控latest_fork_usec指标


9. 混合持久化对重写的影响


Redis 4.0+的混合持久化改变了重写输出格式:


混合持久化重写

遍历内存

生成RDB二进制

后续增量命令

RDB + AOF混合格式

纯AOF重写

遍历内存

生成RESP命令

纯文本AOF


配置

# 开启混合持久化后,重写生成混合格式文件 aof-use-rdb-preamble yes


优势:文件更小、恢复更快


---


总结


| 维度 | 说明 |

|------|------|

|触发方式| 手动BGREWRITEAOF或自动(大小+增长率双条件) |

|核心原理| fork子进程 → 读取内存数据 → 生成最小命令集 |

|增量处理| 重写期间的双写缓冲(aof_buf + 重写缓冲区) |

|文件安全| 先写临时文件,原子替换,防止损坏 |

|风险控制| 内存限流、磁盘空间预留、低峰期执行 |

|最佳实践| 配合混合持久化、设置合理阈值、监控重写耗时 |


http://www.jsqmd.com/news/1232350/

相关文章:

  • Unity特效渲染优化:解决视锥体剔除导致的特效消失问题
  • 生日派对策划 —— 鸿蒙AI智能助手开发全流程解析
  • STM32智能控制台:I2C与SPI双总线实战
  • 2026年7月浙江烧烤喷油泵头/喷油泵头源头工厂推荐_宁波伟倩塑业有限公司 - 品牌宣传支持者
  • 2026年7月小区污水处理设备/甘肃玻璃钢污水处理设备厂家推荐合集_甘肃瑞泽新能源环保科技有限公司 - 品牌宣传支持者
  • 2026年7月福建计数包装机械/计数包装机械厂家口碑推荐_福建省泉州锦文腾机械有限公司 - 品牌宣传支持者
  • C++多态机制深度解析:从虚函数表到设计模式实战
  • 2026年CRM系统选型指南:AI与全渠道融合趋势
  • 野餐准备清单 —— 鸿蒙AI智能助手开发全流程解析
  • 2026年7月喷油泵头/减脂控油喷油泵头品牌推荐名单_宁波伟倩塑业有限公司 - 行业平台推荐
  • 新闻简报的价值与AI芯片技术解析
  • 向量引擎会议纪要转任务上线前:trace_id、重试边界和费用台账怎么验收
  • 瑞芯微开发板固件烧录指南:Windows与Ubuntu双平台实战
  • Python爬虫技术:从基础到实战应用
  • Linux基础命令解析与实战应用指南
  • 纪律就好比软件开发的语法,不可违背
  • Shell 脚本工程化黄金标准:模块化、错误捕获与 GitHub Actions CI 集成防坑指南
  • SolidWorks大国工匠插件安装指南:解决国标出图与标准件调用难题
  • AI提问技术:精准提问方法论与实战技巧
  • 2026年7月一体化污水处理设备/甘肃地埋式污水处理设备制造商推荐名单_甘肃瑞泽新能源环保科技有限公司 - 行业平台推荐
  • AI如何变革学术写作:核心技术解析与实践指南
  • Ubuntu 22.04在树莓派4上的内存优化与性能提升
  • C2000 eQEP边沿捕获单元:实现伺服电机超低速高精度测速
  • Linux命令从入门到精通:系统管理与开发实战指南
  • 企业级AI Agent开发实战:从技术选型到系统集成
  • 2026年7月快船亚马逊FBA头程物流/包税亚马逊FBA头程物流渠道商选哪家_深圳市安速国际货运代理有限公司 - 品牌宣传支持者
  • 用Python实现带排序查找功能链表,这操作绝了
  • 2026来宾房屋渗漏水检测公司口碑榜TOP5推荐-正规防水补漏一站式维修:卫生间/厨房/阳台/屋顶/地下室/屋顶/天沟渗漏水精准测漏补漏上门 - 安佳防水
  • 2026年7月香氛工厂有哪些,洗手间香薰/别墅香氛/蜡片香氛/豪车香薰/游轮香氛/水性香氛精油,香氛OEM品牌口碑推荐 - 品牌推荐师
  • 上海小程序开发公司怎么选?企业为什么不能只看案例和报价