Zookeeper數據模型與session機制:
zookeeper的數據模型有點類似於文件夾的樹狀結構,每一個節點都叫做znode,每一個節點都可以有子節點和數據,就好像文件夾下面可以有文件和子文件夾。
* 每一個節點存儲的數據不宜過大。
* 我們可以為節點設置相應的控制權限。
* 每個節點都帶有版本號,數據變更時,版本號(樂觀鎖)變更。
zookeeper的客戶端與服務端建立連接就會存在session機制,通過客戶端向服務端ping包請求的心跳機制來檢查session是否過期,session過期的時候,該session創建的所有臨時節點都會被拋棄。
Zookeeper的四種類型節點:
persistent: 持久化節點
persistent_sequential: 持久化順序節點
ephemeral: 臨時節點
ephemeral_sequential:臨時順序節點
* 持久化節點只能主動調用detele方法刪除
* 臨時節點在創建者超時或失去連接后節點就會被刪除,臨時節點下面沒有子節點
* 順序節點在創建后會自動在后面添加序列號
Zookeeper集群的三種角色:
leader:一個集群有且只有一個leader節點,處理寫請求,並負責進行發起投票和決議,更新系統狀態。每次處理寫請求的時候都會發起投票,只有過半的節點通過才能寫入數據。
follower:用來處理讀請求,leader會根據算法落實到某個follower節點。follower除了有投票權還具有選舉權,當leader掛掉之后,follower之間就會發起投票,選舉出下一任的leader。
observer:用來處理讀請求,可以當成沒有投票和選舉資格的follower。其存在的目的就是為了協助follower來處理讀請求。因為一個集群只有leader和follower的話每次節點變化都需要投票,這是很耗時間的;有這么一個只干活不投票的打醬油角色可以提高讀取的吞吐量。
* zookeeper集群必須有過半的節點存活才能提供服務。那么5台的集群最多能掛2台機,6台的集群最多也只能掛2台。那么5台和6台沒區別,為了節約服務器成本通常集群為奇數。而不是別人網上說的奇數台這樣投票就會有一個最大值,這是錯誤的說法。
zookeeper的選舉狀態變化:
looking, 選舉中狀態(集群剛啟動或leader宕機時,查找leader的狀態)
leading, 領導者狀態(若節點為leader,那么它就是leading狀態)
following, 隨從者狀態(若節點為follower,它就會同步leader數據,成為following狀態)
observing, 觀察者狀態(若節點為observer,它就會同步leader數據,成為observing狀態)
Zookeeper如和實現數據一致性的:
zk的核心是廣播機制,該機制保證了各個zk之間的數據同步(數據一致性)。zk實現的機制為ZAB協議(zk原子廣播協議),主要原理是下面3中模式。
廣播模式:leader寫入數據時會發起提議,當大多數follower都同意之后,leader就會更新數據並廣播給其他follower。
恢復模式:如果leader崩潰,這個時候就會進入恢復模式,使得整個zk集群恢復到正常的工作狀態。
同步模式:新的leader選舉出來后,就會進入同步模式,各個follower會去同步新的leader上的數據,當大多數節點完成了狀態同步,恢復模式就結束。
Zookeeper集群的選舉算法:
zookeeper集群的機器有兩個核心的屬性,myid和zxid。
myid:是zk集群中服務器的唯一標識,例如有3台zkserver,那么編號分別為1,2,3。
zxid:是一個64位的long類型。它會拆分成2部分,高32位表示epoch(leader標識), 低第32位表示xid(事務id)。
現在我們以3台機器的集群模擬選舉過程:
1. 由於是集群初始化,前面幾個節點都是投自己的票.這個時候集群還沒啟動過半,則這個zkserver的選舉狀態是looking。這時候假定epoch為123,則第一個機器的票數,epoch,myid為 1:123:1。然后將投票信息廣播出去。
2. 啟動第二台機器,它還是投自己的票(n台機器的集群,前面幾台機器都是自己投自己)。此時它的票數,epoch,myid為 1:124:2。廣播給其他節點自己的投票消息。
2.1 此時集群已經啟動過半,可以提供服務了。首先會比較票數,票數多的為leader;票數一樣就比較epoch,值大者(大表示數據越新)勝出;epoch相等就比較myid,myid大的勝出。
2.2 此時第二台機器就是leader,第一台機器就是follower。
3. 啟動第三台機器,由於集群已經產生出leader了,所以節點三也是follower。
3.1 leader選舉出來之后就會產生一個新的zxid,然后所有follower都去同步leader的zxid.其中高32的epoch表示一個新紀元(改朝換代會有新的國號嘛),低32位的xid事務id用來leader提議寫操作(可以理解成一個國家的法律)
4. 若leader無法保持連接的時候就會開始新一輪的投票, 產生新的leader和zxid,然后進行同步 .....
5.1如果之前的leader重啟,那么他會成為一個follower,去同步新的leader信息
5.2如果剛才的leader只是假死,現在它復活之后還會以為自己是leader,那么它向其它follower發生請求會被拒絕。
注意: 因為ZooKeeper維護了一個叫epoch的變量, 每當新leader產生時, epoch都會遞增, followers如果確認了新的leader存在, 同時也會知道其epoch的值。
它們會拒絕epoch小於現任leader的epoch的所有舊leader的任何請求.仍然會存在有部分followers不知道新leader的存在, 但肯定不是大多數, 否則新leader將無法產生.