iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 14
1
Software Development

服務開發雜談系列 第 14

etcd Raft淺談(中) 選舉篇

啟動時的選舉

承上篇, 一開始大家都是Follower, node1的選舉倒數器觸發timeout了, 轉成Candidate, node1會先投票給自己(笑), 並且把Term+1, 發起Request Voteinitial-cluster內的其他節點.

此時其他節點都還在Follower的狀態, 處於Term 0的任期中.

當其他節點收到投票請求時, 會把自己的票投給節點A. 並且更新自己的Term為1, 也會紀錄自己投票給哪個候選者.

Follower也會把election timer重置, 這樣就避免馬上又出現Candidate, 導致選舉失敗.
node1收到node2&3的投票回應後, 因為超過半數(抽屜原理), 所以在Term1這任期, node1就是Leader了.

Leader與Follower日常

Node1成為Leader之後, 會定期被heartbeat timer觸發去對集群中其他節點發送心跳.
刷新其他Follower節點的elction timer, 避免超時而觸發新一輪的選舉.
所以當Follower收到heartbeat後, 會重置election timer, 並且給出heartbeat response. 讓Leader知道Follower也還正常活著.

Leader失效, 重新選舉

node1假如crash了, 或者網路異常發生分區了, 來看看noe2&3會怎做.
這時候其他Follower的election timeout會被觸發, 假設是node2, 它就會轉成Candidate, Term改成第2任, 並且投給自己, 向其他Follower發出選舉請求.
Node3這時收到了選舉請求, 也把自己改成第2任, 票投給node2返回, election timer重置.
Node2收到2票, 又過半了, 正式成為Leader, 就開始繼續發送heart beat.

Node1復活了or網路分區復原了!!!

Node1這時候恢復了, 或者網路復原了, 大家又連的到Node1了, Node1也連的到大家了.
這時Node1會是Follower狀態, 然後會收到來自node2的heart beat, 該訊息內會包含Term資訊, Node1會發現新Leader的Term大於自己, 就會乖乖地更新自己的Term, 變成Follower, 並且重置election timer.

多個Candidate存在怎辦?

假設Node1跟2同任期, 都是Candidate.
同時投票給自己, 同時發選舉請求跟對方跟Node3.
這時候就看Node3投給誰了. (奇數節點的好處)

如果剛好是偶數節點數量呢?
假設現在有Node1-4, Node1&2都是Candidate, 2者都是Term2, Node3&4是Term1.
Node1&2都投票給自己, 也發選舉請求跟對方跟Node3&4.
假設之時Node1的選舉請求先到Node3, Node2的選舉請求則是Node4先收到.
Node3會投給Node1, Node4投給Node2.
此時Node1跟2都沒過半, Term2這任期會宣告選舉失敗.
等時間流逝, 任意節點的election timeout又被觸發時, 會重新發起新一輪選舉(此時就會是Term3)(懶得畫圖QQ)

因此合理的那兩個timer配置非常重要!!!

heartbet timer << election timer
Time Parameters
這裡提到heartbeat最好設置在成功之間的訊號在成員之間往返的平均RTT更大一些些.
election timer則是RTT的10倍.

Source Code

becomeFollower

becomeCandidate

becomeLeader

resetElectionTimerAnd...

tickeElection週期性增加electionElapsed,並檢查是否timeout

tickHeartbeat週期性增加heartbeatElapsed,並檢查是否要發送心跳

下篇再來分享, 日誌怎同步的Raft Visualization操作玩看看

ps. Vote for A(這裡筆誤...都是指note1), 事後我再來修圖


上一篇
etcd Raft淺談(上) 名詞簡介
下一篇
etcd Raft淺談(下) 日誌複製
系列文
服務開發雜談33

尚未有邦友留言

立即登入留言