Redis CLUSTER FAILOVER 命令只能在集群的 slave 节点上执行,让 slave 节点进行一次人工故障切换。人工故障切换是预期的操作,而非发生了真正的故障,目的是以一种安全的方式(数据无丢失)将当前 master 节点和其中一个 slave 节点交换角色。
命令格式
CLUSTER FAILOVER [FORCE|TAKEOVER]
可用版本:>=3.0.0
时间复杂度:O(1)
人工故障的流程是:
- 当前 slave 节点告知其 master 节点停止处理来自客户端的请求。
- master 节点将当前 replication offset 回复给该 slave 节点。
- 该 slave 节点在未应用至 replication offset 之前不做任何操作,以保证 master 传来的数据均被处理。
- 该 slave 节点进行故障转移,从群集中大多数的 master 节点获取 epoch,然后广播自己的最新配置。
- 原 master 节点收到配置更新:解除客户端的访问阻塞,回复重定向信息,以便客户端可以和新 master 通信。
当该 slave 节点(将切换为新 master 节点)处理完来自 master 的所有复制,客户端的访问将会自动由原 master 节点切换至新 master 节点。
CLUSTER FAILOVER,除非执行时使用选项 TAKEOVER,否则故障切换不会同步执行,仅绕过故障检测阶段,添加一个人工故障转移任务。因此如果要检测故障转移是否真的发生了,需要在 CLUSTER FAILOVER 发送一段时间后使用 CLUSTER NODES 或其他方法来验证群集变动后的状态。
命令参数
该命令有如下两个选项:FORCE 和 TAKEOVER:
-
FORCE 选项:
slave 节点不和 master 协商(master 也许已不可达),从上如 4 步开始进行故障切换。当 master 已不可用,而我们想要做人工故障转移时,该选项很有用。但是,即使使用 FORCE 选项,我们依然需要群集中大多数 master 节点有效,以便对这次切换进行验证,同时为将成为新 master 的 salve 节点生成新的配置 epoch。
FORCE 选项使用场景是 master 节点 down 的情况下的人工故障转移。
-
TAKEOVER 选项:
有时会有这种情况,集群中 master 节点不够,我们想在未和集群中其余 master 节点验证的情况下进行故障切换。实际用途举例:集群中主节点和从节点在不同的数据中心,当所有主节点 down 掉或被网络分区隔离,需要用该参数将 slave 节点批量切换为 master 节点。
选项 TAKEOVER 实现了 FORCE 的所有功能,同时为了能够进行故障切换放弃群集验证。当 slave 节点收到命令 CLUSTER FAILOVER TAKEOVER 会做如下操作:
- 独自生成新的 configEpoch,若本地配置 epoch 非最大的,则取当前有效 epoch 值中的最大值并自增作为新的配置 epoch。
- 将原 master 节点管理的所有哈希槽分配给自己,同时尽快分发最新的配置给所有当前可达节点,以及后续恢复的故障节点,期望最终配置分发至所有节点。
注意:TAKEOVER 违反 Redis 集群最新-故障转移-有效原则,因为 slave 节点产生的配置 epoch 会让正常产生的的配置 epoch 无效:
- 使用 TAKEOVER 产生的配置 epoch 无法保证时最大值,因为我们是在少数节点见生成 epoch,并且没有使用信息交互来保证新生成的 epoch 值最大。
- 如果新生成的配置 epoch 恰巧和其他实例生成的发生冲突(epoch 相同),最终我们生成的配置 epoch 或者其他实例生成的 epoch,会通过使用配置 epoch 冲突解决算法 舍弃掉其中一个。
因为这个原因,选择 TAKEOVER 需小心使用。
命令返回值
该命令已被接受并进行人工故障转移回复 OK,切换操作无法执行(如发送命令的已经时 master 节点)时回复错误。