bigywater.tech
Redis · 57

WAIT

Redis 的复制是异步的:主库写完就回复客户端,从库晚一点才收到。WAIT 命令让客户端可以「等一等」:这条写入至少被 N 个从库收到了再往下走。这篇验证它能保证什么、不能保证什么:超时怎么算、返回值代表什么、写入会不会回滚,以及它和 WAITAOF 的区别。

0.14 ms
两个从库都健康时,WAIT 2 的耗时中位数
1
冻结一个从库后,WAIT 2 200 等满 207 ms 的返回值
1018 ms
everysec 下 WAITAOF 1 1 的耗时中位数(WAIT 不到 1 ms)

健康时:几乎零代价

实测 · 本机执行输出
200 次:返回值集合 [2];耗时 中位 0.14 ms,最大 13.98 ms

SET 之后立刻 WAIT 2 100,200 次全部返回 2,耗时中位 0.14 ms、最大 13.98 ms。复制通道本身很快,WAIT 通常不会明显增加延迟。

从库慢/挂了:超时

用 SIGSTOP 冻结从库进程
实测 · 本机执行输出
WAIT 2 200 → 1,耗时 207 ms
WAIT 1 200 → 1,耗时 0.21 ms

冻结从库 B 之后,WAIT 2 200 只能等满 200 ms 超时,返回 1(耗时 207 ms);WAIT 1 200 则在 0.21 ms 就返回 1。第一个参数是「至少要几个」,够数立即返回,不够就等到超时,返回的是超时那一刻实际确认的从库数。

WAIT 不回滚

实测 · 本机执行输出
主库 GET k = during-freeze2   从库 C GET k = during-freeze2
B 恢复后 GET k = during-freeze2

WAIT 返回 1(没有达到 2)之后,主库上的这次写入已经生效,C 能读到,冻结的 B 解冻后也追上了。所以 WAIT 只是「问一问有几个从库收到了」,不是分布式事务:凭返回值没达标就认为「写失败」是错的,该怎么处理要由应用决定。

WAIT 与 WAITAOF

主从都开 appendonly yes,appendfsync everysec
实测 · 本机执行输出
WAIT 2 3000:      返回 [2],耗时 最小 0.14  中位 0.29  最大 5.74 ms
WAITAOF 1 0 3000(仅本地 fsync)    返回 [[1, 0], [1, 0], [1, 0]]…  耗时 最小 1014  中位 1018  最大 1105 ms
WAITAOF 1 1 3000               返回 [[1, 1], [1, 1], [1, 1]]…  耗时 最小 1017  中位 1018  最大 1323 ms
WAITAOF 1 2 3000               返回 [[1, 2], [1, 2], [1, 2]]…  耗时 最小 1017  中位 1018  最大 1762 ms

WAIT 只保证从库把数据收进了内存。WAITAOF numlocal numreplicas timeout 等的是 AOF 的 fsync。在 everysec 下,WAITAOF 1 0 / 1 1 / 1 2 的耗时都是约 1 秒(最小 1017 ms、中位 1018 ms),对应一次 everysec 的 fsync 周期,返回值 [本地已 fsync 数, 从库已 fsync 数]。我第一次跑用的超时是 1000 ms,恰好和这个周期一样长,所以拿到了不完整的结果——超时要比 fsync 周期留出余量。

全部从库冻结

实测 · 本机执行输出
WAIT 1 300 → 0,耗时 368 ms

两个从库都冻结时,WAIT 1 300 等到超时(368 ms)返回 0。给 WAIT 设的超时,就是你为「从库确认」愿意付出的最坏延迟。(超时参数为 0 表示无限等待——这一点没有在这里验证,不建议用。)

分步演示:WAIT 返回什么、等多久

WAIT
本步的数据

    本文用到的工具与边界

    • 本机 macOS 27 / Redis 8.10.2 独立实例(本机回环端口,save 关闭),redis-cli 风格输出由自写的 RESP 客户端打印;计时用 time.perf_counter,数字每次运行会有小幅抖动。一主两从,从库用 SIGSTOP/SIGCONT 冻结与恢复;主从的 appendonly 为 yes、appendfsync everysec
    • 没有验证:WAIT 超时为 0 的行为、网络分区(而非进程冻结)下的表现、集群模式下的 WAIT、appendfsync always 时 WAITAOF 的耗时
    京ICP备2026067502号-1京公网安备11010502063487号