Redis 持久化 AOF
AOF(Append Only File,只追加日志)把每一条写命令追加进日志文件,重启时按顺序重放这些命令即可还原数据。相比 RDB 快照,AOF 能精确到秒级甚至命令级,是追求高可靠性的持久化方案。
开启 AOF
在 redis.conf 中把 appendonly 改为 yes 后重启;也可以运行时直接打开,无需停机:
appendonly yes # 开启 AOF
appendfilename "appendonly.aof" # 日志文件名
appendfsync everysec # 刷盘策略,见下节
127.0.0.1:6379> CONFIG SET appendonly yes
# 输出:OK
127.0.0.1:6379> CONFIG GET appendfsync
# 输出:1) "appendfsync"
# 2) "everysec"
fsync 三种策略
appendfsync 决定多久把日志缓冲区真正刷到磁盘,在性能与可靠性之间取舍:
| 策略 | 刷盘时机 | 最坏丢数据 | 性能 |
|---|---|---|---|
| always | 每执行一条命令 | 最多 1 条命令 | 最慢 |
| everysec | 每秒批量刷一次 | 1~2 秒数据(默认) | 均衡 |
| no | 交给操作系统决定 | 可能较多 | 最快 |
生产环境默认 everysec 即可;对数据极其敏感的场景才考虑 always。
AOF 文件里有什么
AOF 里的命令按 Redis 序列化协议存放,直观来看形如一条条带长度前缀的命令。Redis 7.0 之后 AOF 由三部分协同:base 文件保存上次重写时的全量快照、incr 文件保存之后的增量命令、manifest 文件记录清单,对使用者无需关心内部细节。
*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n # 即 SET key value
AOF 重写
运行越久日志越大,可用 BGREWRITEAOF 重写:只保留能还原当前数据的“最终命令”,体积明显变小,期间主进程不阻塞:
127.0.0.1:6379> SET user:1 Tom
127.0.0.1:6379> SET user:1 Jerry # user:1 被反复覆盖多次
127.0.0.1:6379> BGREWRITEAOF
# 输出:Background append only file rewriting started
自动重写由两个配置控制,体积超过下限且比上次重写增长超过比例时触发:
auto-aof-rewrite-percentage 100 # 增长超过 100% 时考虑重写
auto-aof-rewrite-min-size 64mb # 至少达到 64mb 才重写
文件损坏处理
断电可能导致日志尾部写了一半。Redis 默认容忍截断的尾部(aof-load-truncated yes)正常启动;若文件彻底损坏,用自带工具修复:
redis-check-aof --fix appendonly.aof
# 输出:AOF analyzed: size=..., ... 已移除损坏的命令段
修复只能救回能救的数据,重要环境应靠日常备份兜底,不能把修复当常态。
与 RDB 如何取舍
RDB 是二进制快照,文件小、恢复快,但两次快照之间的数据可能丢失;AOF 记录每条写命令,丢数据窗口小,但文件大、启动重放慢。两者其实互补——Redis 7 起 AOF 重写产生的 base 文件直接采用 RDB 格式,这就是“混合持久化”。
小结:AOF 以“追加日志 + 后台重写”换取比 RDB 更小的数据丢失窗口;建议 appendonly yes 配 appendfsync everysec。两种方案如何组合选型、如何做灾难恢复,见下一章。