首页/数据/Redis 进阶速查/AOF 原理:追加日志与重放
持久化56 条

AOF 原理:追加日志与重放

AOF 把每条写命令追加到日志文件,重启时按顺序重放恢复数据;写入先进入内存缓冲,再按 appendfsync 策略刷盘。

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

AOF 是什么

AOF(Append Only File)是 Redis 的日志式持久化:把每一条会改变数据的写命令按执行顺序追加到文件末尾,重启时从头重放这些命令,重建出与宕机前一致的数据集。它的思路与 RDB 相反,RDB 保存的是某一时刻的数据结果,AOF 保存的是造成这些结果的操作过程,因此 AOF 丢失窗口通常更小,代价是文件更大、恢复更慢。Redis 2.4 之后把 AOF 改成边写内存缓冲边追加文件,才让它真正进入生产可用状态。

基本信息

开关appendonly yes|no(默认 no,可用 CONFIG SET 动态开启)
文件位置dir 目录下;旧版单文件 appendonly.aof,7.0 起为 appendonlydir/ 目录
刷盘策略appendfsync everysec(默认)/ always / no
恢复优先级开启 AOF 且文件存在时优先于 RDB 加载
配套工具BGREWRITEAOF 重写、redis-check-aof 校验修复

典型使用场景

  • 订单、账务、会话关键状态这类秒级丢失也不可接受的业务,靠 AOF 把丢失窗口压到最小
  • 与 RDB 双开做分层防线:AOF 负责近实时恢复,RDB 负责冷备与快速重放基线
  • 需要复盘「数据是怎么被写坏的」时,AOF 本身就是一份可读的命令序列
  • 从纯 RDB 环境平滑过渡到 AOF:动态开启 appendonly,后台立即生成本次基线文件
  • 小体量实例做日常留档,重写后的 AOF 可直接拷贝到备份介质

开启与观察

开启与观察
redis-cli CONFIG SET appendonly yes      # 动态开启,后台立即生成本次基线
redis-cli CONFIG GET appendfsync         # 查看刷盘策略
redis-cli INFO persistence | grep -E 'aof_enabled|aof_last_write_status'
ls -l /var/lib/redis/appendonlydir/      # 7.0 起的多文件结构
redis-cli BGREWRITEAOF                   # 压缩命令历史,回落文件体积
redis-cli -h 10.0.0.12 CONFIG GET appendonly   # 从库是否同样开启

写入链路三段

阶段动作相关配置
命令追加写命令执行后追加进 aof_buf 内存缓冲appendonly
缓冲刷盘后台线程按策略把缓冲 write 到 AOF 文件appendfsync
落盘确认fsync 把页缓存写入磁盘介质,决定真实丢失窗口appendfsync
文件重写子进程按当前内存数据生成紧凑版本并替换旧文件auto-aof-rewrite-percentage
AOF 记录的是导致数据变化的命令,而不是客户端原始请求:过期键被删除产生的 DEL、EXPIRE 设置的过期时间、Lua 脚本内部执行的写、被淘汰键的移除,都会以派生命令的形式落盘,所以 AOF 重放出来的状态与内存一致。
版本差异:7.0 起 AOF 拆成 base 基线文件加多个 incr 增量文件,由 manifest 描述;旧版本只有一个 appendonly.aof。备份与迁移脚本要按实际版本适配,不要照搬单文件路径。

常见故障与处置

现象根因处置顺序
写入全部报 MISCONFAOF 或 RDB 刷盘失败先查磁盘空间与目录权限,清理后确认 aof_last_write_status 回到 ok
启动日志提示 truncated断电导致文件尾部命令不完整备份原文件,再用 redis-check-aof --fix 截断到最后一个完整命令
文件体积持续增大自动重写未触发或长期失败核对 auto-aof-rewrite-percentage 与磁盘余量,手动 BGREWRITEAOF 验证
切换后新主库无 AOF从库当初未开启 appendonly所有实例统一配置,避免故障切换后持久化能力忽然降级
AOF 与复制是两条独立链路:从库收到的是主库转发的命令流,而不是主库的 AOF 文件。因此从库的 appendonly 需要在每个实例上单独开启,否则切换后新主库可能没有任何持久化保护。
AOF 持续写入失败会把实例带进 MISCONF 写保护,所有写请求直接报错;磁盘满、目录权限错误这类问题不会自愈,发现 aof_last_write_status 为 err 必须立刻处理。

易错点

  • 把默认的 everysec 当成零丢失:断电场景下仍有约 1 秒窗口,需要零丢失只能 always,而上线前必须压测确认吞吐能承受
  • 文件尾部因断电被截断时,Redis 默认加载到最后一个完整命令并只写日志告警,表现为启动成功但尾部数据已丢,必须结合业务对账确认
  • 不配置自动重写导致 AOF 随命令历史持续膨胀,磁盘被慢慢吃满后触发写保护,往往是线上写入全面报错的根因
  • 关闭 appendonly 不会删除历史 AOF 文件,存在遗留文件时实际加载来源与预期不符,恢复演练要按真实加载路径验证

数据来源与参考

  • Redis 官方文档:AOF 持久化说明
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌