Redis WAIT 命令阻塞当前客户端,直到所有先前的写入命令成功传输,并且由至少指定数量的副本(slave)确认。在达到指定数量的副本或超时时,该命令将始终返回确认在 WAIT 命令之前发送的写入命令的副本数量。
命令格式
WAIT numreplicas timeout
可用版本:>=3.0.0
时间复杂度:O(1)
值得注意的是,WAIT 不能保证 Redis 的强一致性;虽然同步复制是复制状态机的一部分,但它并不是必需的。但是,在 Sentinel 或 Redis 集群故障转移时,WAIT 可提高数据安全性。
如果将给定的写入传输到一个或多个副本,成功可能性大(但不能保证);如果主服务器出现故障,我们将能够在故障转移期间提升接收到写入的副本;Sentinel 和 Redis Cluster 将尽最大努力在可用副本集中选择最佳的副本。但是,这只是一次尽力而为的尝试,因此仍有可能丢失同步复制到多个副本的写入。
命令参数
- numreplicas:指定副本(slave)的数量。
- timeout:超时时间,时间单位为毫秒;当设置为 0 时,表示无限等待,即用不超时。
命令返回值
WAIT 命令返回在当前连接的上下文中执行的所有写入所达到的副本数。
如果该命令是作为 MULTI 事务的一部分发送的,则该命令不会阻塞,而是仅返回 ASAP 确认先前写入命令的副本的数量。
注释:由于 WAIT 命令不管是成功或失败时,都返回达到副本的数量,所以客户端有必要检查返回的值是否等于或大于它所要求的复制等级。
同步扩展
Redis 在 2.8 版本开始引入了增量同步机制(PSYNC),Redis 从节点使用该机制对已在复制流中处理的偏移量异步地对其主节点进行 ping 操作,以达到如下几种目的:
- 检测超时的从节点。
- 断开连接后执行部分重新同步。
- 执行 WAIT。
在实现 WAIT 的特定情况下,Redis 会在每个客户端记住在给定客户端的上下文中,执行给定写入命令时生成的复制流的复制偏移量。当调用 WAIT 时,Redis 会检查指定数量的副本是否已经确认了此偏移量或更大的偏移量。
示例
redis> SET Aki Sasaki
OK
redis> WAIT 1 0
(integer) 1
redis> WAIT 2 1000
(integer) 1
在以上示例中,对 WAIT 的第一次调用不使用超时,并要求写入达到 1 个副本,并且其成功返回。在第二次尝试中,我们设置了超时时间 1000 毫秒,并要求将写入复制到 2 个副本。由于只存在单个副本,因此在 1 秒等待阻塞后,解除阻塞并返回 1,即达到了 1 个副本。