上圖中節(jié)點(diǎn)C占據(jù)了先機(jī),率先發(fā)起競(jìng)選投票。
節(jié)點(diǎn)B慢了一步, 無奈中同意支持節(jié)點(diǎn)C , 節(jié)點(diǎn)C獲得了超過半數(shù)的支持,成為“老大” , 節(jié)點(diǎn)B成為“小弟”。
(可能有人會(huì)想到:節(jié)點(diǎn)B和節(jié)點(diǎn)C 同時(shí)發(fā)起競(jìng)選投票,每個(gè)節(jié)點(diǎn)的投票計(jì)數(shù)都是1 ,都過不了半數(shù), 該怎么處理呢? 很簡(jiǎn)單,再次發(fā)起一輪競(jìng)選投票即可,當(dāng)然為了防止B和C一直同時(shí)發(fā)起競(jìng)選投票,從而陷入無限循環(huán),要重置一個(gè)隨機(jī)的等待時(shí)間。)
投票過半數(shù)很重要,張大胖想,只有這樣才能保證“老大”節(jié)點(diǎn)的唯一性。
對(duì)于每個(gè)節(jié)點(diǎn),處理流程其實(shí)非常簡(jiǎn)單:
3.數(shù)據(jù)的復(fù)制
張大胖費(fèi)了半天勁,終于把分布式系統(tǒng)中怎么自動(dòng)地選取“老大”節(jié)點(diǎn)給確定了。
接下來就是要把發(fā)給“老大”的數(shù)據(jù),想辦法復(fù)制到“小弟”的節(jié)點(diǎn)上。 該怎么處理?
由于是分布式的,只有大多數(shù)節(jié)點(diǎn)都成功地保存了數(shù)據(jù),才算保存成功。
所以那個(gè)“老大”節(jié)點(diǎn)必須得承擔(dān)起協(xié)調(diào)的職責(zé)。
張大胖想了一個(gè)復(fù)制日志的辦法: 每個(gè)節(jié)點(diǎn)都有一個(gè)日志的隊(duì)列。
在真正把數(shù)據(jù)提交之前,先把數(shù)據(jù)追加到日志隊(duì)列中,然后向個(gè)“小弟”復(fù)制。
1. 客戶端發(fā)送數(shù)據(jù)給節(jié)點(diǎn)A (“老大”)。
節(jié)點(diǎn)A 先把數(shù)據(jù)記錄到日志中,即此時(shí)處于“未提交狀態(tài)”
2. 在下一次的心跳消息中, 數(shù)據(jù)被發(fā)送給各個(gè)“小弟”。
3. 各個(gè)“小弟” 也把數(shù)據(jù)記錄到日志中(也處于未提交狀態(tài)),然后向“老大”報(bào)告自己已經(jīng)記錄了日志。
4. 如果節(jié)點(diǎn)A收到響應(yīng)超過了半數(shù), 節(jié)點(diǎn)A就提交數(shù)據(jù),通知客戶端數(shù)據(jù)保存成功。
5. 節(jié)點(diǎn)A在下一次心跳消息中,通知各個(gè)“小弟”該數(shù)據(jù)已經(jīng)提交。各個(gè)“小弟”也提交自己的數(shù)據(jù)。
如果某個(gè)“小弟”不幸掛掉,那“老大”會(huì)不斷地嘗試聯(lián)系它, 一旦它重新開始工作,就需要從“老大”那里去復(fù)制數(shù)據(jù),和“老大”保持一致。
4.RAFT
張大胖對(duì)這個(gè)初步的設(shè)計(jì)還比較滿意,他把這個(gè)方案交給領(lǐng)導(dǎo)Bill去審查。
Bill 看了以后,笑道: “你現(xiàn)在其實(shí)就是在折騰一個(gè)一致性算法, 說白了就是允許一組機(jī)器像一個(gè)整體一樣工作,即使其中一些機(jī)器出現(xiàn)故障也能夠繼續(xù)工作下去。”
“沒錯(cuò)沒錯(cuò),領(lǐng)導(dǎo)總結(jié)得真是精準(zhǔn)。” 張大胖拍馬屁。
“不過,”Bill 話鋒一轉(zhuǎn), “ 你設(shè)計(jì)的日志的復(fù)制還有很多漏洞,我看你的設(shè)計(jì)中一共有5步, 如果在這5步中,那個(gè)“老大”節(jié)點(diǎn)A掛掉了怎么辦?數(shù)據(jù)是不是就不一致了?”
“這個(gè)...... ” 張大胖確實(shí)沒有仔細(xì)考慮。他暗自后悔,只顧低頭拉車,忘了抬頭看路,忽略了分布式環(huán)境下的復(fù)雜問題。
“不過你已經(jīng)做得很不錯(cuò)了,” 領(lǐng)導(dǎo)馬上鼓勵(lì)道, “你設(shè)計(jì)的這一套體系其實(shí)和RAFT算法非常類似。”
“RAFT? ”
“對(duì),RAFT是個(gè)分布式的一致性算法,相比復(fù)雜難懂的Paxos, RAFT在可理解,可實(shí)現(xiàn)性上做了很大的改進(jìn)。 你這里的‘老大’,RAFT算法叫做Leader, ‘小弟’叫做Follower,不過人家對(duì)日志的復(fù)制,以及如何確保數(shù)據(jù)的一致性有著非常詳細(xì)的規(guī)定。 ”
張大胖一聽說有現(xiàn)成的算法,立刻高興起來: “太好了,分布式的難題已經(jīng)被別人解決,我去把它實(shí)現(xiàn)了。”