
1. 重写的核心目的AOF文件记录了所有写命令随着服务运行时间增长文件体积会不断膨胀带来三个问题| 问题 | 影响 ||------|------||磁盘空间占用| 日志文件可能比实际数据大数十倍 ||数据恢复缓慢| Redis重启时需重放海量命令耗时从分钟级到小时级 ||网络传输压力| 主从复制时传输大文件占用带宽 |举例对同一Key执行100万次INCRAOF会记录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 重写缓冲区 ||文件安全| 先写临时文件原子替换防止损坏 ||风险控制| 内存限流、磁盘空间预留、低峰期执行 ||最佳实践| 配合混合持久化、设置合理阈值、监控重写耗时 |