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 写保护导致全部写入失败。这个字段必须纳入监控告警。