redis-cluster不可用情況
1、集群主庫半數宕機
2、集群某個節點的主從全數宕機
當某個master掛掉后,在cluster集群仍然可用的前提夏,由於某個master有多個slave,某個slave提升為master,這個過程稱為選舉。
currentEpoch 這是一個集群狀態相關的概念,可以當作記錄集群狀態變更的遞增版本號。每個集群節點,都會通過server.cluster->currentEpoch記錄當前的currentEpoch。
集群節點創建時,不管是master還是slave,都置currentEpoch為0.當前節點接收到來自其他節點的包時,如果發送者的currentEpoch大於當前節點會更新currentEpoch為發送者的currentEpoch。因此,集群的所有節點從currentEpoch最終會達成一致,相當於對集群狀態的認知達成了一致。
過程如下
1、slave發現自己的master變為FAIL
2、發起選舉前,slave先給自己的epoch加1,然后請求其它master給自己投票。slave是通過廣播FAILOVER_AUTH_REQUEST包給集中的每個masters。
3、slave發起投票后,會等待至少兩倍NODE_TIMEOUT時長接收自己投票結果,不管NODE_TIMEOUT何值,也至少會等待2秒。
4、master接收投票后給slave響應FAILOVER_AUTH_ACK,並且在NODE_TIMEOUT*2 時間內不會給同一個master的其他slave投票。
5、如果slave收到FAILOVER_AUTH_ACK響應的epoch值小於自己的epoch,則會直接丟棄。以但slave收到多數master的FAILOVER_AUTH_ACK則聲明自己贏得選舉。
6、如果slave在兩倍的NODE_TIMEOUT時間內至少2秒未贏得選舉,則放棄本次選舉,然后4倍NODE_TIMEOUT時間發起再次選舉
之所以強制延遲至少0.5秒選舉,是為確保master的fail狀態在整個集群內傳開,否則可能只有小部分master知曉,而master只會給處於fail狀態的master的slaves投票。
如果一個slave的master狀態不是fail,則其他的master不會給它投票,redis通過八卦協議傳播fail。而在固定延遲上再加一個隨機延遲是為了多高slaves同時發起選舉。
延遲計算公式:
DELAY = 500 + RANDOM(0~500)+SLAVE_RANK*1000ms
SLAVE_RANK表示此slave已經從master復制的數據越新。這種方式下,持有最新數據的slave將會首先發起選舉。
