appendfsync 决定 AOF 什么时候真正落盘:always 每次写命令都 fsync,everysec 每秒一次,no 交给操作系统。教科书说 always 最安全、最慢。这篇量「慢」到底是多慢:延迟、吞吐、并发下的表现,数字都来自本机(苹果电脑的 SSD,fsync 成本与 Linux 服务器不同,请当作方法而不是结论)。
appendfsync p50 µs p99 µs max µs 平均 µs always 2707 3484 9370 2267 everysec 31 99 235 34 no 30 51 113 33
always 的每条写命令要等 fsync 完成才回复:p50 2.71 ms、p99 3.48 ms,一个客户端只能到约 441 条/秒。everysec 和 no 的延迟几乎一样(31 µs 对 30 µs)——everysec 的 fsync 在后台线程里,不在请求路径上。
always 72k 条/秒 everysec 545k 条/秒 no 551k 条/秒
管道 2000 条一批:always 72k/s,everysec 545k/s,no 551k/s。批量之后 always 的 fsync 摊到整批,吞吐比单条同步高得多,但仍只有 everysec 的约 13%。
appendfsync 1 客户端 8 客户端 放大倍数 always 424/s 2263/s 5.3 everysec 30777/s 87857/s 2.9 no 34050/s 88866/s 2.6
8 个独立进程各自同步 SET:always 的总吞吐从 424/s 涨到 2263/s(5.3 倍),放大倍数明显高于 everysec(2.9 倍)和 no(2.6 倍)。从数字看,多个客户端的写命令共用了 fsync;为什么能共用(猜测是同一轮事件循环里的写命令一起 fsync),我没有读源码验证。所以 always 在高并发下的代价,比单客户端测出来的低得多。
{'always': '0', 'everysec': '0', 'no': '0'}三种模式下 aof_delayed_fsync 都是 0,说明这台机器的磁盘在这种负载里跟得上。这个指标在 everysec 下用来发现「fsync 拖累了主线程」,如果它持续增长,说明磁盘慢。
真正的持久性差别——断电时到底丢多少——没有测。我用的是进程被杀、操作系统仍然存活的场景(第 60 篇),这时页缓存里的数据不会丢,三种模式看不出差别。断电级别的丢失需要真正切断电源或使用带故障注入的文件系统,这里做不到,所以本文只回答性能,不回答安全。