bigywater.tech
Redis · 64

appendfsync always/everysec/no

appendfsync 决定 AOF 什么时候真正落盘:always 每次写命令都 fsync,everysec 每秒一次,no 交给操作系统。教科书说 always 最安全、最慢。这篇量「慢」到底是多慢:延迟、吞吐、并发下的表现,数字都来自本机(苹果电脑的 SSD,fsync 成本与 Linux 服务器不同,请当作方法而不是结论)。

2.71 ms vs 31 µs
SET 的 p50 延迟:always vs everysec(单客户端同步)
7.6 倍
管道批量写入时 everysec 比 always 的吞吐优势(545k vs 72k/s)
5.3 倍
8 个客户端并发时 always 的总吞吐放大(多个写共用一次 fsync)

一个客户端:每条命令的延迟

每种模式一个新实例,3000 条同步 SET,统计每条的往返
实测 · 本机执行输出
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%。

并发客户端:always 会被「合并」

实测 · 本机执行输出
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 在高并发下的代价,比单客户端测出来的低得多。

aof_delayed_fsync

实测 · 本机执行输出
{'always': '0', 'everysec': '0', 'no': '0'}

三种模式下 aof_delayed_fsync 都是 0,说明这台机器的磁盘在这种负载里跟得上。这个指标在 everysec 下用来发现「fsync 拖累了主线程」,如果它持续增长,说明磁盘慢。

这个实验没有回答的问题

真正的持久性差别——断电时到底丢多少——没有测。我用的是进程被杀、操作系统仍然存活的场景(第 60 篇),这时页缓存里的数据不会丢,三种模式看不出差别。断电级别的丢失需要真正切断电源或使用带故障注入的文件系统,这里做不到,所以本文只回答性能,不回答安全。

分步演示:三种模式的代价

appendfsync
本步的数据

    本文用到的工具与边界

    • 本机 macOS 27 / Redis 8.10.2 独立实例(本机回环端口,save 关闭),redis-cli 风格输出由自写的 RESP 客户端打印;计时用 time.perf_counter,数字每次运行会有小幅抖动。macOS + Apple SSD;Linux 服务器的 fsync 成本、磁盘类型不同,数字不可直接套用。并发实验用独立进程避开 GIL
    • 没有验证:断电场景的数据丢失量、Linux 下的数字、磁盘更慢或带写缓存电池时的差别、appendfsync everysec 下 fsync 阻塞主线程时的延迟(需要慢盘)、aof_delayed_fsync 增长的触发条件
    京ICP备2026067502号-1京公网安备11010502063487号