參考資料: http://thesecretlivesofdata.com/raft/
1. 選舉算法:
我們來模擬一下 RAFT算法的 選舉過程
1.1. 粗糙的選舉過程描述
角色:
- 領導者 leader
- 候選人 candidate
- 跟隨者 follower
背景:
- 假設: 此時每個節點記錄的
任期編號爲1
, 節點A是leader領導者節點
開始選舉:
- 集羣中, A節點leader下線, A節點不再向各個節點發送心跳包
- 每個節點開始計算leader的心跳包超時時間(每個節點是隨機的)
- B節點第一個到超時時間
- B節點設置自己的
任期編號爲2
, 發送投票請求給其他所有節點 - 其他節點如果是發現自己的任期編號小於2, 則將投票給B節點
- 當B節點接收到的贊同票超過半數, 則選舉結束
- 節點B加冕爲王, 開始向其他所有節點發送心跳包, 宣示主權
1.2. 處理衝突
以上的描述過於粗糙, 還有許多細節問題我們需要一一處理
問題1: 如果有多個節點一起發出投票請求, 接受者怎麼處理?
- 同一個任期, 我只能投一次票, 誰的請求先發給我我就先給誰投票
- 無論我是什麼角色, 如果收到一個投票請求, 比我的任期編號高, 我立刻轉換身份變成跟隨者, 並給它投票
問題2: 如果沒有一個候選者獲得半數以上的投票怎麼辦?
- 如果候選者沒有獲得半數以上投票, 那麼候選者開始計算超時時間(隨機時間), 等待下一次發起投票, 候選者超時時間較短, 跟隨者超時時間較長
2. 日誌同步
日誌同步的算法就要簡單得多
步驟:
- 客戶端向領導者發起請求,設置a=1
- 領導者接收請求,修改數據,暫時hold住請求
- 領導者將修改同步給其他所有節點
- 跟隨者接收到請求之後修改自己節點上的值 a=1, 這只是半提交
- 跟隨者發送修改成功的消息通知領導者
- 當領導者收到
半數以上
跟隨者修改成功的消息之後, 通知客戶端修改成功 - 同時領導者通知跟隨者確認剛纔修改的值 a=1 修改成功
- 這裏使用了二階段提交的算法, 3, 7, 兩步就是兩次提交的步驟
3. 成員變更
成員變更的算法也很簡單
爲了防止出現腦裂的情況發生, 成員變更, 尤其是增加成員, 我們一般採取單節點變更的方式
- 單節點變更, 就是通過一次變更一個節點實現成員變更
- 如果有多個節點需要變更, 則需要執行多次單成員變更, 多次變更是串行的
步驟:
- 新節點向集羣註冊自己
- leader節點向新節點同步數據
- 領導者將新節點的配置同步到其他跟隨者節點上
- 完成