問(wèn)題
FollowerA在選舉超時(shí)后拍谐,沒(méi)收到心跳, 然后會(huì)發(fā)起選舉,并轉(zhuǎn)為Candidate瀑志。每次發(fā)起選舉時(shí)小槐,會(huì)把Term加一。但是由于網(wǎng)絡(luò)隔離拍屑,或者說(shuō)其他的大部分節(jié)點(diǎn)還正常連著leader途戒,因此它不會(huì)被選成Leader,可是也不會(huì)收到Leader的消息僵驰,所以會(huì)一直不斷地發(fā)起選舉喷斋。Term會(huì)不斷增大。
一段時(shí)間之后蒜茴,這個(gè)節(jié)點(diǎn)的Term會(huì)非常大星爪。在網(wǎng)絡(luò)恢復(fù)之后,這個(gè)節(jié)點(diǎn)會(huì)把它的Term傳播到集群的其他節(jié)點(diǎn)粉私,導(dǎo)致其他節(jié)點(diǎn)更新自己的term顽腾,變?yōu)镕ollower。然后觸發(fā)重新選主,但這個(gè)舊的Follower_2節(jié)點(diǎn)由于其日志不是最新抄肖,并不會(huì)成為L(zhǎng)eader久信。整個(gè)集群被這個(gè)網(wǎng)絡(luò)隔離過(guò)的舊節(jié)點(diǎn)擾亂,顯然需要避免的漓摩。
舉例:
有A,B,C,D,E五臺(tái)機(jī)裙士,A是leader,某個(gè)時(shí)刻A,B出現(xiàn)了分區(qū)管毙,但是A,C,D,E以及B,C,D,E都可以互相通信腿椎。B在超時(shí)沒(méi)有收到心跳后,把term+1夭咬,發(fā)起leader選舉啃炸,如果這段時(shí)間C,D,E沒(méi)有寫入更新的日志,由于B的term更大皱埠,就會(huì)被選為leader肮帐,A在后面的RPC中因?yàn)樽约旱膖erm較小也會(huì)被降為follower。問(wèn)題是A成為follower之后又會(huì)按照上面B的方式發(fā)起選舉成為leader边器,同理B也會(huì)再次發(fā)起選舉训枢,這樣周而復(fù)始會(huì)造成很大的網(wǎng)絡(luò)開銷。
解決方案
上面描述的是非對(duì)稱網(wǎng)絡(luò)分區(qū)的情況忘巧,如果不做特殊處理恒界,會(huì)反復(fù)出現(xiàn)新的選舉,打斷正常的 IO砚嘴,這里一般可以通過(guò) pre-vote 解決十酣,例如,每次發(fā)起選舉之前际长,先發(fā)起 pre-vote 如果獲得大多數(shù) pre-vote 選票耸采,再增大 term 發(fā)起選舉 vote 投票。為了避免問(wèn)題描述的情況工育,其他節(jié)點(diǎn)只需要在收到 pre-vote 請(qǐng)求時(shí)虾宇,判斷一下 leader 是否還在,一般實(shí)現(xiàn)上如绸,判斷最近和 leader 是否正常通信嘱朽,如果有,那么說(shuō)明 leader 正常在線怔接,直接拒絕 pre-vote 即可搪泳。
或者用租約,follower只要在租期(屬于某個(gè)leader)內(nèi)扼脐,如果不是強(qiáng)制轉(zhuǎn)移leader岸军,那么就忽略term大的votemsg。