集群故障转移
Syntax
CLUSTER FAILOVER [FORCE | TAKEOVER]
- Available since:
- 3.0.0
- Time complexity:
- O(1)
- ACL categories:
-
@admin
,@slow
,@dangerous
,
此命令只能发送到Redis集群的副本节点,强制副本开始对其主实例进行手动故障转移。
手动故障转移是一种特殊类型的故障转移,通常在没有任何实际故障时执行,但我们希望以安全的方式将当前主节点与其副本之一(即我们发送命令的节点)交换,而不会出现任何数据丢失的窗口。它的工作方式如下:
- 副本告诉主服务器停止处理来自客户端的查询。
- 主节点回复副本当前的复制偏移量。
- 副本等待其端的复制偏移量匹配,以确保在继续之前处理了来自主节点的所有数据。
- 副本启动故障转移,从大多数主节点获取新的配置纪元,并广播新配置。
- 旧主节点接收到配置更新:解除对其客户端的阻塞,并开始回复重定向消息,以便它们继续与新主节点进行聊天。
这样,客户端会从旧的主节点原子性地移动到新的主节点,并且只有在转变为新主节点的副本处理完来自旧主节点的所有复制流时才会进行。
FORCE 选项:当主服务器宕机时手动故障转移
命令行为可以通过两个选项进行修改:FORCE 和 TAKEOVER。
如果给出了FORCE选项,副本不会与可能无法访问的主服务器进行任何握手,而是直接从第4点开始尽快启动故障转移。这在我们想要在主服务器不再可访问时启动手动故障转移时非常有用。
然而,使用FORCE我们仍然需要大多数主节点可用,以便授权故障转移并为即将成为主节点的副本生成新的配置纪元。
TAKEOVER 选项:无需集群共识的手动故障转移
在某些情况下,这还不够,我们希望一个副本在不与集群其他部分达成一致的情况下进行故障转移。一个现实世界的用例是,在不同的数据中心中大规模将副本提升为主节点,以执行数据中心切换,而所有主节点都宕机或分区。
TAKEOVER 选项意味着包含 FORCE 的所有含义,但此外,它不会使用任何集群授权来进行故障转移。接收到 CLUSTER FAILOVER TAKEOVER
的副本将执行以下操作:
- 单方面生成一个新的
configEpoch
,只需获取当前可用的最大纪元,并在其本地配置纪元尚未达到最大值时递增它。 - 将主节点的所有哈希槽分配给自己,并尽快将新配置传播到每个可达的节点,最终传播到其他所有节点。
请注意,TAKEOVER 违反了 Redis 集群的最后故障转移获胜原则,因为副本生成的配置纪元在多个方面违反了配置纪元的正常生成方式:
- 不能保证它实际上是更高的配置时期,因为,例如,我们可以在少数派中使用TAKEOVER选项,也不会执行任何消息交换来生成新的配置时期。
- 如果我们生成的一个配置纪元恰好与另一个实例发生冲突,最终我们的配置纪元,或者另一个具有相同纪元的实例的配置纪元,将会使用配置纪元冲突解决算法被移开。
因此,应谨慎使用TAKEOVER选项。
实现细节和注意事项
CLUSTER FAILOVER
,除非指定了TAKEOVER选项,否则不会同步执行故障转移。 它只是安排了一个手动故障转移,跳过了故障检测阶段。- 一个
OK
回复并不能保证故障转移会成功。 - 一个副本只有在被集群中的大多数主节点识别为副本时,才能被提升为主节点。
如果该副本是刚刚添加到集群中的新节点(例如在升级后),它可能尚未被集群中的所有主节点识别。
要检查主节点是否识别了新副本,您可以在向副本发送
CLUSTER FAILOVER
之前,向每个主节点发送CLUSTER NODES
或CLUSTER REPLICAS
,并检查它是否显示为副本。 - 要检查故障转移是否实际发生,您可以使用
ROLE
、INFO REPLICATION
(在成功故障转移后显示“role:master”),或CLUSTER NODES
来验证集群状态在命令发送后是否发生了变化。 - 要检查故障转移是否失败,请检查副本的日志中是否有“手动故障转移超时”,如果副本在几秒钟后放弃,则会记录此信息。
RESP2/RESP3 回复
Simple string reply:OK
if the command was accepted and a manual failover is going to be attempted. An error if the operation cannot be executed, for example if the client is connected to a node that is already a master.