appendfsync always 会让 Redis 突然变慢,因为每次写命令后都同步调用 fsync() 阻塞主线程,SSD 单次耗时 0.2–1ms,高并发下排队导致延迟飙升至几十毫秒,aof_delayed_fsync 上涨、P99 延迟突增、日志报“AOF fsync is taking too long”均为典型表现。

为什么 appendfsync always 会让 Redis 突然变慢
因为每次写命令执行完,Redis 都得调用 fsync() 强制刷盘——这个系统调用会卡住主线程,直到磁盘确认落盘完成。SSD 上单次 fsync 平均耗时 0.2–1ms,但高并发下排队叠加,延迟直接飙到几十毫秒,INFO persistence 里 aof_delayed_fsync 持续上涨就是典型信号。
- 现象:客户端偶发超时、
redis-cli --latency显示 P99 延迟突增、日志出现Asynchronous AOF fsync is taking too long - 根本原因不是 Redis 慢,是磁盘 I/O 被堵住,而
always把所有写请求都绑在了同一根 I/O 绳子上 -
everysec用独立后台线程做fsync,主线程只负责write()到内核缓冲区,快一个数量级 - 别迷信“金融级安全”——真要零丢失,得配双机同步 + WAL 日志 + 应用层幂等,单靠
always解决不了原子性问题
appendfsync everysec 的真实风险和兜底动作
它不是“每秒刷一次就绝对丢 1 秒数据”,而是:后台 aof_fsync 线程每秒触发一次 fsync,但如果这次 fsync 因磁盘忙而卡住,下一次不会覆盖,而是排队等待;此时若进程崩溃,未刷盘的缓冲区(最多 1 秒)就丢了。
- 风险点:当
aof_delayed_fsync > 0持续存在,说明后台线程已滞后,实际丢失窗口可能远超 1 秒 - 必须开:
no-appendfsync-on-rewrite yes,否则 AOF 重写期间fsync和重写进程抢磁盘,主线程 write 会被阻塞 - 监控命令:
redis-cli info persistence | grep -E "aof_delayed_fsync|aof_pending_bio_fsync",这两个值非零就要查磁盘负载 - 别只看配置,检查磁盘本身:用
iostat -x 1看%util是否长期 >80%,await是否 >10ms
什么时候可以关掉 AOF 刷盘,或换用 no
不是“能不能丢数据”,而是“丢了之后业务是否可自愈”。比如 Session 缓存、实时排行榜临时分、搜索建议热词——这些数据本就该由下游服务重建,AOF 反而成了性能累赘。
- 适用场景:
no模式下,全靠操作系统决定刷盘时机(通常 30s 内),TPS 能比everysec再提 20%~30% - 前提条件:必须搭配
aof-use-rdb-preamble yes(混合持久化),保证重启时能快速加载 RDB 快照,避免 AOF 回放慢成瓶颈 - 危险操作:把
no用在有状态的计数器(如库存扣减)、用户积分变更上——没刷盘就宕机,数据不一致很难修复 - 验证方法:停掉 Redis,强制 kill -9,再启动,用
redis-cli keys *对比前后 key 数量和值,确认业务容忍范围
绕过刷盘瓶颈的硬核手段
调策略只是治标。真正压垮性能的,往往是 AOF 文件越滚越大、重写频繁、磁盘吞吐跟不上写入节奏。这时候得动底层。
- 升硬件:AOF 日志盘必须用 NVMe SSD,SATA SSD 在高并发写入下
fsync延迟抖动极大 - 调内核:
vm.dirty_ratio=10和vm.dirty_background_ratio=5,让脏页更早异步刷出,缓解突发写压 - 文件系统挂载加
data=writeback(ext4)或mount -o noatime,减少元数据更新开销 - CPU 绑定:
server_cpulist 0-3+bio_cpulist 4-5,把主线程和后台刷盘线程隔离到不同物理核,避免缓存颠簸
everysec 也会退化成半 always。先看 iostat,再改配置。


















