等待 AOF 同步
WAITAOF numlocal numreplicas timeout
- 可用版本
- 7.2.0
- 时间复杂度
- O(1)
- ACL 类别
-
@slow
,@connection
,
此命令会阻塞当前客户端,直到该客户端之前的所有写入命令都被确认已同步到本地 Redis 的 AOF 文件,或者至少同步到指定数量的副本。
numlocal
表示在继续执行之前需要确认的本地 fsync 次数。当 numlocal
设置为 1 时,命令会阻塞,直到写入 Redis 实例的数据被确认已持久化到本地 AOF 文件。值为 0 会禁用此检查。
如果在以毫秒为单位指定的超时时间到达之前,未达到指定的确认次数,则命令会立即返回。
该命令始终会返回在执行 WAITAOF
命令之前,已将当前连接发送的所有写入命令同步到 AOF 文件的主节点和副本的数量,无论是否满足指定的阈值,以及是否达到超时时间。
一些说明
- 当
WAITAOF
返回时,所有在当前连接上下文中发送的之前的写入命令都保证已同步到 AOF 文件,至少同步到WAITAOF
返回的主节点和副本数量。 - 如果该命令是在
MULTI
事务(或任何其他不允许阻塞的上下文,例如在脚本中)中执行,则命令不会阻塞,而是立即返回已将所有之前的写入命令同步到 AOF 文件的主节点和副本的数量。 - 超时时间为 0 表示永远阻塞。
- 由于
WAITAOF
在成功和超时情况下都会返回完成的 fsync 次数,因此客户端应该检查返回值是否大于或等于所需的持久化级别。 WAITAOF
无法在副本实例上使用,并且如果本地 Redis 未启用 AOF,则numlocal
参数不能为非零值。
局限性
可以编写模块或 Lua 脚本,将写入传播到 AOF,但不会传播到复制流。(对于模块,这是通过使用 RedisModule_Call
或 RedisModule_Replicate
的 fmt
参数实现的;对于 Lua 脚本,这是通过使用 redis.set_repl
实现的。)
这些功能与 WAITAOF
命令的当前实现不兼容,并且组合使用它们可能会导致不正确行为。
一致性和 WAITAOF
请注意,与 WAIT
类似,WAITAOF
不会使 Redis 成为强一致性存储。除非等待集群中的所有成员将写入同步到磁盘,否则在故障转移或 Redis 重新启动期间仍可能丢失数据。但是,WAITAOF
确实提高了实际数据安全性。
实现细节
从 Redis 7.2 开始,Redis 即使在未配置任何副本的情况下(只要存在 AOF)也会跟踪并递增复制偏移量。
此外,Redis 副本会异步 ping 它们的主节点,并发送两个复制偏移量:它们在复制流中已处理的偏移量,以及它们已同步到其 AOF 的偏移量。
Redis 会为每个客户端记住在当前连接上下文中执行最后一个写入命令时产生的复制流的复制偏移量。当调用 WAITAOF
时,Redis 会检查本地 Redis 和/或指定数量的副本是否已确认将此偏移量或更大的偏移量同步到其 AOF 文件。
示例
> SET foo bar
OK
> WAITAOF 1 0 0
1) (integer) 1
2) (integer) 0
> WAITAOF 0 1 1000
1) (integer) 1
2) (integer) 0
在上面的示例中,第一次调用 WAITAOF
没有使用超时时间,并且要求将写入同步到本地 Redis。当此操作完成时,它会返回 [1, 0]。
在第二次尝试中,我们指定了一个超时时间,并要求确认单个副本已将写入同步到 AOF 文件。由于没有连接的副本,因此 WAITAOF
命令在一秒钟后解除阻塞,并再次返回 [1, 0],表明写入已同步到本地 Redis,但尚未同步到任何副本。
RESP2/RESP3 响应
数组响应:该命令返回包含两个整数的数组
- 第一个是已将当前连接上下文中执行的所有写入同步到 AOF 文件的本地 Redis 的数量(0 或 1)
- 第二个是已确认执行相同操作的副本的数量。