cluster failover force/takeover
只能在replica节点上执行,强制对他的master节点执行failover
cluster failover
执行的场景:
没有实际的failure,但是希望master发生主从切换(具体哪一个从提升为主,看在哪一个主上执行cluster failover),切换是一个安全的方式,没有任何数据丢失。工作的流程是:
- step1 副本告诉主:停止接受来自client的查询请求
- step2 主回复副本当前的replication offset
- step3 副本等待replication offset和主的一致,保证主的数据都被同步过来了
- step4 副本开始failover,包含一个来自多数master的configuration epoch,然后广播新的配置文件
- step5 老的master 收到配置文件的更新:解锁他的client,开始回复redirection messages告诉client去找新的master
最终,旧的master的client连接会自动地转移到新的master;只有旧master的所有replication stream同步完成,副本才会变成新的master。
cluster failover force:当master挂掉之后手动执行failover
执行逻辑:
当master挂掉了,副本将连接不到master。副本直接从step4开始执行;但是使用force我们需要得到多数master的投票,因为需要认证副本的failover操作,从而生成一个新的configuration epoch对于即将成为master的副本
cluster failover takeover:不需要集群投票达到共识就可以手动failover
- 执行场景:
希望对一个副本执行failover不需要集群的投票。使用场景是:需要将多数的replicas都提升为masters(多数masters down或者出现分区) - 执行逻辑:当一个副本收到cluster failover takeover的命令
- step1 单方面生成一个新的configEpoch,如果本地配置的configEpoch不是集群里最大的则增加它(只取当前可用的最大的epoch)
- step2 把master的槽都设置成自己,然后广播给其他节点
- 注意:谨慎使用
- takeover违反了集群的last-failover-wins原则,因为执行该命令的replica生成configEpoch没有遵循正常的流程。这样不能保证它实际上是最高的configEpoch。如果我们生成的configEpoch和其他实例发生冲突,将由configuration epoch collision resolution algorithm解决
返回结果
- ok为成功
具体实现细节
- cluster failover不会同步执行failover,除非使用了takeover选项。它只是执行了手动的failover,绕过了故障检测阶段
- ok并不能保证failover成功
- 如果一个副本多数节点都承认它是某个master的副本,该副本执行failover之后会被提升为master。如果一个replica是一个新加入集群的节点,集群里的其他节点可能还不认识它,你需要在每一个master节点check通过cluster nodes和cluster replicas
- 检查failover是否实际成功,可以使用info replication或者cluster nodes
- 如果failover失败,可以查看replica的日志是否有Manual failover timed out,这条日志将会在replica尝试几秒未果之后打印
Cluster replicate node-id
如果一个master角色的节点收到这个命令,这个节点的角色会变成replica,同时把node-id的节点当作主。一个master节点执行这个命令成功的前提是:
- 该master节点没有槽
- 节点是空的,keyspace没有数据
如果一个节点变成其他master节点的replica,不会去告知其他的集群节点关于这个变化。节点之间的heartbeat pkg会传播新的配置文件
一个replica执行这个命令成功的前提:
- node-id存在在节点本身的nodes table
- node-id和该节点要相互认识(提前meet进入集群)
- node-id是一个master节点
cluster meet ip port
该命令作用:将一个开启了cluster-enable的节点,加入集群
基本思想:一个新节点和集群内的节点互不认识,所以集群内的节点不会自动把这个新节点(system administration errors or network addresses modifications)加入集群,需要手动操作
为了将一个特定的节点加入集群,两种方式:
- 在A节点上send cluster meet B,强迫A meet B
- 已经在集群内的节点会给其他节点发送gossip包。如果B接受了A的meet,就会给A发一个gossip包to handshake
集群内的链接是一个full mesh,新节点不需要meet所有的集群内节点,新节点只要被集群内的某个节点认可,其他节点也会认可它(通过gossip信息的心跳包)
meet操作是相互的,A meet B(A会发给B一个meet包,而不是ping包。返回ok表示成功),不需要在B上执行 B meet A了。