一旦ZooKeeper集合啟動,它將等待客戶端連接。客戶端將連接到ZooKeeper集合中的一個節(jié)點。它可以是領(lǐng)導(dǎo)或跟隨者節(jié)點。一旦客戶端被連接,節(jié)點將向特定客戶端分配會話ID并向該客戶端發(fā)送確認。如果客戶端沒有收到確認,它將嘗試連接ZooKeeper集合中的另一個節(jié)點。 一旦連接到節(jié)點,客戶端將以有規(guī)律的間隔向節(jié)點發(fā)送心跳,以確保連接不會丟失。
如果客戶端想要讀取特定的znode,它將會向具有znode路徑的節(jié)點發(fā)送讀取請求,并且節(jié)點通過從其自己的數(shù)據(jù)庫獲取來返回所請求的znode。為此,在ZooKeeper集合中讀取速度快。
如果客戶端想要將數(shù)據(jù)存儲在ZooKeeper集合中,則會將znode路徑和數(shù)據(jù)發(fā)送到服務(wù)器。連接的服務(wù)器將該請求轉(zhuǎn)發(fā)給領(lǐng)導(dǎo)者,然后領(lǐng)導(dǎo)者將向所有的跟隨著重新發(fā)出寫入請求。如果只有大部分節(jié)點成功響應(yīng),而寫入請求成功,則成功返回代碼將被發(fā)送到客戶端。 否則,寫入請求失敗。絕大多數(shù)節(jié)點被稱為 Quorum 。
ZooKeeper集合中可以有不同數(shù)量的節(jié)點。那么,讓我們分析一下在ZooKeeper工作流中更改節(jié)點的效果:
如果我們有單個節(jié)點,那么當(dāng)該節(jié)點失敗時,ZooKeeper集群就會失效。這就是為什么不建議在生產(chǎn)環(huán)境中使用它,因為它會導(dǎo)致"單點故障"。
如果我們有兩個節(jié)點和一個節(jié)點故障,我們就沒有多數(shù),因為兩個節(jié)點中有一個不是多數(shù)節(jié)點。
如果我們有三個節(jié)點而一個節(jié)點故障,那么我們有大多數(shù),因此,這是最低要求。ZooKeeper集群在實際生產(chǎn)環(huán)境中必須至少有三個節(jié)點。
如果我們有四個節(jié)點而兩個節(jié)點故障,它將再次故障。類似于有三個節(jié)點,額外節(jié)點不用于任何目的,因此,最好添加奇數(shù)的節(jié)點,例如3,5,7。
我們知道寫入過程比ZooKeeper集合中的讀取過程昂貴,因為所有節(jié)點都需要在數(shù)據(jù)庫中寫入相同的數(shù)據(jù)。因此,對于平衡的環(huán)境擁有較少數(shù)量(例如3,5,7)的節(jié)點比擁有大量的節(jié)點要好。
下圖描述了ZooKeeper工作流,后面的表說明了它的不同組件。
組件 | 描述 |
---|---|
寫入(write) | 寫入過程由leader節(jié)點處理。leader將寫入請求轉(zhuǎn)發(fā)到所有znode,并等待znode的回復(fù)。如果一半的znode回復(fù),則寫入過程完成。 |
讀取(read) | 讀取由特定連接的znode在內(nèi)部執(zhí)行,因此不需要與集群進行交互。 |
復(fù)制數(shù)據(jù)庫(replicated database) | 它用于在zookeeper中存儲數(shù)據(jù)。每個znode都有自己的數(shù)據(jù)庫,每個znode在一致性的幫助下每次都有相同的數(shù)據(jù)。 |
領(lǐng)導(dǎo)者(Leader) | Leader是負責(zé)處理寫入請求的Znode。 |
跟隨者(Follower) | follower從客戶端接收寫入請求,并將它們轉(zhuǎn)發(fā)到leader znode。 |
請求處理器(request processor) | 只存在于leader節(jié)點。它管理來自follower節(jié)點的寫入請求。 |
原子廣播(atomic broadcasts) | 負責(zé)廣播從leader節(jié)點到follower節(jié)點的變化。 |
更多建議: