5.6. 通信故障
5.6.1.故障检测
集群中的每个节点都会定期地向集群中的其他节点发送PING消息,以此交换各个节点状态信息,检测各个节点状态:在线状态、疑似下线状态PFAIL、已下线状态FAIL。
当主节点A通过消息得知主节点B认为主节点D进入了疑似下线(PFAIL)状态时,
主节点A会在自己的clusterState.nodes字典中找到主节点D所对应的clusterNode结构,
并将主节点B的下线报告(failure report)添加到clusterNode结构的fail_reports链表中
struct clusterNode {
//...
//记录所有其他节点对该节点的下线报告
list*fail_reports;
//...
};
每个下线报告有一个clusterNodeFailReport结构:
struct clusterNodeFailReport{
//报告目标节点已经下线的节点
structclusterNode *node;
//最后一次从node节点收到下线报告的时间
mstime_ttime;
}typedef clusterNodeFailReport;
如果集群里面,半数以上的主节点都将主节点D报告为疑似下线,那么主节点D将被标记为已下线(FAIL)状态,将主节点D标记为已下线的节点会向集群广播主节点D的FAIL消息,
所有收到FAIL消息的节点都会立即更新nodes里面主节点D状态标记为已下线。
将node标记为FAIL需要满足以下两个条件:
1.有半数以上的主节点将node标记为PFAIL状态。
2.当前节点也将node标记为PFAIL状态。
5.6.2.选取主节点
从多个从节点选择主节点,选新主节点的过程基于Raft协议选举方式来实现。
![](/qrcode.jpg)
1、当从节点发现自己的主节点进行已下线状态时,从节点会广播一条
CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST消息,要求所有收到这条消息,并且具有投票权的主节点向这个从节点投票。
2、如果一个主节点具有投票权,并且这个主节点尚未投票给其他从节点,那么主节点将向要求投票的从节点返回一条,CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK消息,表示这个主节点支持从节点成为新的主节点。
3、每个参与选举的从节点都会接收CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK消息,并根据自己收到了多少条这种消息来统计自己获得了多少主节点的支持。
4、如果集群里有N个具有投票权的主节点,那么当一个从节点收集到大于等于集群N/2+1张支持票时,这个从节点就成为新的主节点。
5、如果一个从节点没有收集到足够的支持票数,那么集群进入一个新的配置纪元,并再次进行选主,直到选出新的主节点为止。
5.6.3.故障转移
当从节点发现自己的主节点变为已下线(FAIL)状态时,便尝试进Failover,以期成为新的主。
以下是故障转移的执行步骤:
1、从下线主节点的所有从节点中选中一个从节点;
2、被选中的从节点执行SLAVEOF NO NOE命令,成为新的主节点;
3、新的主节点会撤销所有对已下线主节点的槽指派,并将这些槽全部指派给自己;
4、新的主节点对集群进行广播PONG消息,告知其他节点已经成为新的主节点;
5、新的主节点开始接收和处理槽相关的请求。