ZK的選舉
先定義一些名詞:
投票Vote:
包含兩個主要信息哮幢,
- zxid(事務ID,某個操作會有全局唯一的事務ID)志珍,
- SID(當前機器的編號橙垢,集群內(nèi)唯一)
除了這兩個之外,還包括以下三個信息:
- electionEpoch:類似于raft中的term伦糯,邏輯時鐘柜某,用于判斷多個投票是否在同一輪選舉周期中。該值在服務端是一個自增序列舔株,每次進入新一輪的投票后莺琳,都會對這個值進行+1操作
- peerEpoch: 被推舉的leader的epoch
- state:當前服務器的狀態(tài),詳見下
服務器狀態(tài):
LOOKING:尋找Leader狀態(tài)载慈,表示當前服務器認為集群中沒有l(wèi)eader惭等,因此需要進入Leader選舉流程
FOLLOWING:跟隨者狀態(tài),表示當前服務器是Follower
LEADING:領(lǐng)導者狀態(tài)办铡,表示當前服務器是Leader
OBSERVING: 觀察者狀態(tài)辞做,表示當前服務器角色是Observer
算法中的描述
- vote_sid:接收到的投票中所推舉Leader服務器的sid
- vote_zxid: 接收到的投票中所推舉Leader服務器的zxid
- self_sid: 當前服務器本身的sid
- self_zxid:當前服務器本身的zxid
選舉規(guī)則:
- 如果vote_zxid 大于self_zxid,那么認可當前收到的投票寡具,并再次將該投票發(fā)送出去
- 如果vote_zxid 小于self_zxid秤茅,那么堅持自己的投票,不做任何變更
- 如果vote_zxid等于self_zxid童叠,那么對比這兩者的sid
- 如果vote_sid大于self_sid框喳,那么認可當前的投票,并再次將該投票發(fā)送出去
- 如果vote_sid小于self_sid厦坛,那么堅持自己的投票五垮,不做任何變更。
通常來說杜秸,哪臺服務器上的數(shù)據(jù)越新放仗,那么就越有可能成為leader,因為zxid也越大撬碟。
zk只允許sid大的服務器主動和其他較小的sid服務器建立連接诞挨,否則斷開連接。服務器通過對比自己和遠程服務器的sid判斷是否接收連接請求呢蛤,如果當前服務器發(fā)現(xiàn)自己的sid較大惶傻,那么會斷開當前連接,然后自己主動去和遠程服務器建立連接其障。
投票只有來自于LOOKING服務器的才有效达罗。如果當前服務器不是LOOKING狀態(tài),說明已經(jīng)有Leader了,直接忽略這個投票粮揉,同時將leader信息以投票的方式發(fā)送出去巡李。
選舉輪次
也就是epoch(也稱為logicalclock),選舉的前提是在同一個epoch內(nèi)扶认,如果發(fā)現(xiàn)外部的epoch大于本身的侨拦,會立即更新自己的logicalclock,并清空已收到的投票辐宾。
只有在同一個選舉輪次的投票才是有效的投票狱从。