WAIT
WAIT numreplicas timeout
- 可用版本
- Redis 开源版 3.0.0
- 时间复杂度
- O(1)
- ACL 类别
-
@slow
,@blocking
,@connection
,
此命令会阻塞当前客户端,直到之前的所有写命令成功传输并被至少 numreplicas
参数中指定的副本数确认。如果达到了 timeout
参数指定的值(以毫秒为单位),即使尚未达到指定数量的副本,命令也会返回。
该命令**总是返回**在 WAIT
命令之前由当前客户端发送的写命令已被确认的副本数,无论是在达到指定副本数的情况下,还是在达到超时的情况下。
注意事项
- 当
WAIT
返回时,可以保证当前连接上下文中发送的所有先前写命令已被WAIT
返回的副本数接收。 - 如果该命令作为
MULTI
事务的一部分发送(从 Redis 7.0 开始,任何不允许阻塞的上下文,例如脚本内部),该命令不会阻塞,而是尽快返回已确认先前写命令的副本数。 - 超时设置为 0 意味着永久阻塞。
- 由于
WAIT
在失败和成功的情况下都返回已达到的副本数,客户端应检查返回的值是否等于或大于其要求的复制级别。
一致性和 WAIT 命令
请注意,WAIT
并不能使 Redis 成为一个强一致性存储:虽然同步复制是复制状态机的一部分,但它不是唯一必需的条件。然而,在 Sentinel 或 Redis 集群故障转移的上下文中,WAIT
提高了实际数据安全性。
具体而言,如果给定的写入已传输到一个或多个副本,那么在主节点发生故障时,故障转移期间更有可能(但不保证)提升已接收该写入的副本:Sentinel 和 Redis Cluster 都将尽最大努力在可用副本集中提升最佳副本。
但这只是尽力而为的尝试,因此即使写入已同步复制到多个副本,仍然可能丢失数据。
实现细节
自引入与副本的部分重同步(PSYNC 功能)以来,Redis 副本会通过异步 ping 主节点并附带其在复制流中已处理的偏移量。这用于多种用途:
- 检测超时的副本。
- 断开连接后执行部分重同步。
- 实现
WAIT
命令。
在 WAIT
命令的具体实现中,Redis 会记住每个客户端在给定客户端上下文中执行给定写命令时产生的复制流的复制偏移量。当调用 WAIT
命令时,Redis 会检查指定数量的副本是否已经确认了该偏移量或更大的偏移量。
示例
> SET foo bar
OK
> WAIT 1 0
(integer) 1
> WAIT 2 1000
(integer) 1
在以下示例中,第一次调用 WAIT
命令没有使用超时,并要求写入到达 1 个副本。它成功返回。而在第二次尝试中,我们设置了超时,并要求将写入复制到两个副本。由于只有一个副本可用,一秒后 WAIT
会解除阻塞并返回 1,即已达到的副本数。