appendfsync 是什么
AOF 打开后,Redis 把写命令先追加到缓冲区,何时真正调用 fsync 落盘由 appendfsync 决定,共三档:always、everysec、no。这一项直接决定两件事:进程崩溃或断电时会丢多少数据,以及写入吞吐能到什么水平。它是持久化参数里最需要业务方参与决策的一项。
基本信息
| 取值 | always / everysec / no |
|---|---|
| 默认值 | everysec |
| 查看 | CONFIG GET appendfsync,或 redis.conf 中的 appendfsync 行 |
| 生效方式 | CONFIG SET 立即生效,CONFIG REWRITE 才会写回配置文件 |
| 关联配置 | no-appendfsync-on-rewrite,控制重写期间是否暂停 fsync |
典型使用场景
- 评估「Redis 崩溃会丢多久的数据」,与业务方对齐可接受窗口
- 订单、支付类场景在安全性与吞吐之间做取舍
- 写入吞吐偏低时确认是不是用了 always,并评估换盘方案
- 重写期间出现 IO 抖动,决定是否让重写期暂停 fsync
- 容量与延迟调优后复核持久化参数,避免被隐式改回默认值
查看与调整
查看与调整
CONFIG GET appendfsync # 默认 everysec
CONFIG SET appendfsync everysec # 运行时调整,重启前需 CONFIG REWRITE
CONFIG GET no-appendfsync-on-rewrite # 重写期间是否暂停 fsync
CONFIG REWRITE # 把当前内存配置写回 redis.conf
INFO persistence | grep aof_last_write_status
INFO persistence | grep aof_last_bgrewrite_status三档策略对比
| 取值 | 行为 | 丢失窗口与代价 |
|---|---|---|
| always | 每条写命令在返回前完成 fsync | 几乎不丢,但吞吐最低,需要高 IOPS 的盘 |
| everysec | 后台线程每秒执行一次 fsync | 最多丢约 1 秒写入,吞吐与安全的折中 |
| no | 不主动 fsync,交给内核脏页策略 | 可能丢数十秒数据,速度最快也最危险 |
| no-appendfsync-on-rewrite yes | 重写期间不 fsync,避免双份写盘 | 降低 IO 争抢,但丢失窗口被拉长 |
everysec 的 1 秒是「Redis 进程崩溃」的窗口;整机断电时,即使 always 也可能丢掉最后一次尚未 fsync 的写入。要求绝对不丢,需要在应用层做确认或改用具备同步提交语义的存储。
为了性能把 appendfsync 改成 no 属于典型的技术债:故障时丢失窗口从 1 秒变成几十秒,事后无法向业务解释数据为何消失。改之前要有明确的书面决策记录。
排查写入延迟时先确认 AOF 与 RDB 是否同时在忙碌:一个实例上 BGSAVE 与 AOF 重写叠加,fsync 会被磁盘队列拖慢,表现为与持久化活动强相关的周期性卡顿。