整體過程
當(dāng)讀請(qǐng)求,則當(dāng)前節(jié)點(diǎn)獲取;若是寫請(qǐng)求,則轉(zhuǎn)發(fā)給leader,leader提交事務(wù)前,則先廣播事務(wù),超過過半節(jié)點(diǎn)寫入成功,則寫請(qǐng)求被提交
一個(gè)關(guān)鍵問題是leader節(jié)點(diǎn)和follow節(jié)點(diǎn)的數(shù)據(jù)一致性如何保證吞鸭。
ZAB 協(xié)議
zab協(xié)議主要解決集群中節(jié)點(diǎn)的數(shù)據(jù)一致性塞颁。
zab 協(xié)議介紹
ZAB 協(xié)議包含兩種基本模式,分別是
- 崩潰恢復(fù)
當(dāng)lead掛了,則通過崩潰恢復(fù)選擇出新的leader和完成leader和過半的節(jié)點(diǎn)之間的數(shù)據(jù)同步。 - 原子廣播
消息廣播的實(shí)現(xiàn)原理
消息廣播的過程實(shí)際上是一個(gè)簡(jiǎn)化版本的二階段提交過程勾徽。
1 leader節(jié)點(diǎn)將proposal消息發(fā)給所有的follower;follower則把proposal消息寫入磁盤,寫入成功后發(fā)ack;
2 當(dāng)leader節(jié)點(diǎn)收到過半節(jié)點(diǎn)的ack后,向follower節(jié)點(diǎn)發(fā)送commit并在本地執(zhí)行該命令,向連接的客戶端返回成功;follower收到commit命令后,提交該消息氓癌。
問題:會(huì)存在某一個(gè)時(shí)刻follower節(jié)點(diǎn)和leader節(jié)點(diǎn)數(shù)據(jù)不一致谓谦。
崩潰恢復(fù)的實(shí)現(xiàn)原理
崩潰恢復(fù)做兩件事:選舉出新的 leader和數(shù)據(jù)同步。
哪些場(chǎng)景會(huì)導(dǎo)致數(shù)據(jù)不一致
已經(jīng)被處理的消息不能丟
在follower節(jié)點(diǎn)沒有收到commit請(qǐng)求,leader節(jié)點(diǎn)掛了顽铸。
被丟棄的消息不能再次出現(xiàn)
在leader生成Proposal消息后掛了,則該leader所在的機(jī)器重新啟動(dòng)時(shí)要忽略該消息茁计。
解決辦法
針對(duì)上述場(chǎng)景,leader選舉算法要求是能夠確保已經(jīng)被 leader 提交的事務(wù)
Proposal 能夠提交料皇、同時(shí)丟棄已經(jīng)被跳過的事務(wù) Proposal谓松。
1 選舉的leader的服務(wù)器的zxid最大,就可以保證該機(jī)器擁有事務(wù)proposal,因?yàn)橹挥谐^半數(shù)的機(jī)器發(fā)送ack后,leader才能發(fā)送commit提交。
2 zxid 是 64 位,高32位表示epoch,每經(jīng)過一次leader選舉,則epoch+1;低32位表示消息技術(shù)器,沒收到一次消息則+1,新leader選舉后則該值置為0;當(dāng)老leader重啟后,新leader會(huì)把它擁有的舊的epoch號(hào)但未被提交的Proposal刪掉践剂。
ZXID
表示事務(wù)id,zookeeper采用遞增的事務(wù)id表示事務(wù)鬼譬。所有的proposal都會(huì)加一個(gè)事務(wù)id。
數(shù)據(jù)同步包
public class QuorumPacket implements Record {
private int type;
private long zxid;
private byte[] data;
}