故障檢測
集群中的每個節點都會定期地向集群中的其他節點發送PING消息,以此來檢測對方是否在線,如果接收PING消息的節點沒有在規定的時間內,向發送PING消息的節點返回PONG消息,那么發送PING消息的節點就會將接收PING消息的節點標記為疑似下線(probable fail,PFAIL)。
故障轉移
當一個節點從節點發現自己正在復制的主節點進入了已下線狀態時,從節點將開始對下線主節點進行故障轉移,以下是故障轉移的執行步驟:
- 復制下線主節點的所有從節點里面,會有一個從節點被選中。
- 被選中的從節點會執行SLAVEOF no one命令,成為新的主節點。
- 新的主節點會撤銷所有對已下線主節點的槽指派,并將這些槽全部指派給自己。
- 新的主節點向集群廣播一條PONG消息,這條PONG消息可以讓集群中的其他節點立即知道這個節點已經由從節點變成了主節點,并且這個主節點已經接管了原本由已下線節點負責處理的槽。
- 新的主節點開始接收和自己負責處理的槽有關的命令請求,故障轉移完成。
新的主節點是通過選舉產生的,以下是集群選舉新的主節點的方法:
- 集群的配置紀元是一個自增計數器,它的初始值為0。
- 當集群里的某個節點開始一次故障轉移操作時,集群配置紀元的值會被增一。
- 對于每個配置紀元,集群里每個負責處理槽的主節點都有一次投票的機會,而第一個向主節點要求投票的從節點將獲得主節點的投票。
- 當從節點發現自己正在復制的主節點進入已下線狀態時,從節點會向集群廣播一條CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST消息,要求所有收到這條消息、并且具有投票權的主節點向這個從節點投票。
- 如果一個主節點具有投票權(它正在負責處理槽),并且這個主節點尚未投票給其他從節點,那么主節點將向要求投票的從節點返回一條CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK消息,表示這個主節點支持從節點成為新的主節點。
- 每個參與選舉的從節點都會接收CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK消息,并根據自己收到了多少條這種消息來統計自己獲得了多少節點的支持。
- 如果集群里有N個具有投票權的主節點,那么當一個從節點??到大于等于N/2+1張支持票時,這個從節點就會當選為新的主節點。
- 因為這個每一個配置紀元里面,每個具有投票權的主節點只能投一次票,所有如果有N個主節點進行投票,那么具有大于等于N/2+1張支持票的從節點只會有一個,這確保了新的主節點只會有一個。
- 如果在一個配置紀元里面沒有從節點能夠收集到足夠多的支持票,那么集群進入一個新的配置紀元,并在此進行選舉,知道選出新的主節點為止。