首页/数据/Redis 进阶速查/BGREWRITEAOF:AOF 重写
持久化56 条

BGREWRITEAOF:AOF 重写

重写由子进程根据当前内存数据生成新 AOF:期间新写入进入重写缓冲,重写完成后追加上缓冲并原子替换旧文件,文件体积随之回落。

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

AOF 重写是什么

AOF 记录的是操作过程,同一个键被反复修改的次数多了,文件里就堆积了大量中间状态。重写要解决的就是这个膨胀问题:由子进程根据当前内存中的数据直接生成一份紧凑的新 AOF,相当于把「这么久以来做过什么」压缩成「现在是什么」。重写期间新到达的写命令会被暂存到重写缓冲区,子进程写完后把这些缓冲追加到新文件末尾,再用新文件替换旧文件,切换过程对业务没有中断。

基本信息

手动命令BGREWRITEAOF,后台执行、立即返回
自动触发auto-aof-rewrite-percentage 与 auto-aof-rewrite-min-size 共同决定
进度观测INFO persistence 的 aof_rewrite_in_progress 与 aof_last_bgrewrite_status
内存开销与快照相同,需要 fork 子进程并产生 COW 复制
效果多次 INCR 压缩为一次 SET,过期键与已删除键不再出现在新文件中

典型使用场景

  • 磁盘告警后紧急压缩:AOF 文件异常膨胀时手动触发重写释放空间
  • 高频写入后的常规维护:按自动重写配置维持文件体积在合理区间
  • 上线前后基线整理:发布前重写一次,让后续增量文件的起点更干净
  • 迁移准备:先重写缩小体积再拷贝,能显著缩短传输时间
  • 排查重写失败:观察 aof_last_bgrewrite_status 是否为 err,定位磁盘或内存问题

触发与观测

触发与观测
redis-cli BGREWRITEAOF                        # 手动触发,后台执行
redis-cli INFO persistence | grep -E 'aof_rewrite_in_progress|aof_last_bgrewrite_status'
redis-cli INFO persistence | grep -E 'aof_current_size|aof_base_size'   # 重写前后对比
redis-cli CONFIG GET auto-aof-rewrite-percentage    # 默认 100,即增长一倍触发
redis-cli CONFIG GET auto-aof-rewrite-min-size      # 默认 64mb,低于此值不触发
redis-cli CONFIG SET auto-aof-rewrite-percentage 50 # 按业务写入量调整,更频繁但文件更小

自动触发条件

参数含义调整方向
auto-aof-rewrite-percentage相对上次重写后体积的增长比例写密集业务调小,文件更小但重写更频繁
auto-aof-rewrite-min-size触发重写的最小体积门槛小实例可适当调低,避免长期不触发
两者关系体积增长达到百分比且超过最小体积才触发只看百分比的配置在小实例上可能长期不重写
重写不清空也不影响内存数据:它读取的是 fork 时刻内存数据的视图,业务写入照常进行,只是这些新命令会先进入重写缓冲区,等新文件生成后一并追加。因此重写不会造成数据丢失,也不会阻塞请求,代价主要是 fork 停顿与期间的内存增量。
重写失败是静默风险:失败不会中断业务,只会让 aof_last_bgrewrite_status 变成 err,文件继续膨胀直到磁盘被占满,随后触发 MISCONF 写保护导致全部写入失败。这个字段必须纳入监控告警。

易错点

  • 在业务高峰或内存水位高时触发重写,fork 加 COW 的开销与写入叠加,可能触发 OOM 或明显的请求抖动
  • 不监控 aof_last_bgrewrite_status,重写长期失败无人处理,等到磁盘写满时表现为全量写入报错
  • 只看百分比参数而忽略最小体积门槛,小实例上体积虽然翻倍但仍低于 64MB,重写长期不触发
  • 把重写当作数据备份手段:重写只是压缩文件,物理磁盘损坏时新文件同样消失,备份仍需独立机制

数据来源与参考

  • Redis 官方文档:BGREWRITEAOF 命令
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌