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協議選舉方式來實現。
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、新的主節點開始接收和處理槽相關的請求。