现场是这样的。Redis 6.2 跑在 4 核 8G 的 ECS 上,为了不丢数据把 appendfsync 改成 always,QPS 从两万掉到八百,接口平均延迟从 1ms 涨到 30ms,AOF 所在云盘的 await 一直挂在 8ms 左右。

中间走过弯路,把「用的是普通云盘,单盘 IOPS 只有几百,随机同步写根本顶不住」当成主因,改完现象没变。

真正麻烦的地方在于,几个原因的现象几乎一样。always 要求每条命令都落盘,一次 fsync 就是一次同步 IO 等待;AOF 重写和主线程的 fsync 抢同一块盘,重写期间延迟更高;没开 aof-use-rdb-preamble,重写出来的文件更大,恢复也更慢。

动手时先确认刷盘策略和实际延迟

redis-cli config get appendfsync && redis-cli --latency -h 127.0.0.1

然后看 AOF 重写是否同时在跑

redis-cli info persistence | grep -E 'aof_rewrite|aof_last_bgrewrite'

随后改成 everysec 观察吞吐变化

redis-cli config set appendfsync everysec

等前面都确认过,再重写期间先不做 fsync

redis-cli config set no-appendfsync-on-rewrite yes

别只看报错消失,验证要多做一步。QPS 回到一万以上,--latency 的 p99 降到 3ms 以内,AOF 文件增长平稳,重写期间没有明显抖动。

容易忽略的是,always 只适合写少又对丢失零容忍的场景,每秒几万写用它等于把盘当瓶颈;everysec 最多丢一秒,绝大多数业务能接受。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。

作者 9823189