再聊聊zookeeper

聊完kafka必不可少的需要再聊一聊zk了,下面開始

一、ZK是什麼

ZooKeeper是分佈式應用程序的高性能協調服務。它可以實現分佈式的選主、統一配置管理,命名,分佈式節點同步,分佈式鎖等分佈式常用功能;它以path節點的形式保存數據,每個節點都可以存儲數據,因爲ZK只是分佈式的協調者而不推薦做數據庫,所以需要減少沒必要的寫操作,確保對外提供的服務高效、快速,因此其節點的最大容量限制爲1M;

1、ZK的節點類型

  • 持久節點 即客戶端創建後不會隨着客戶端的下線而消失,會一直存在;
  • 臨時節點 即隨着客戶端的下線而被刪除;這裏需要說下的是,zk會給每個客戶端創建一個session,且該session是會同步到集羣其他節點的;

2、ZK的幾個特徵

  • 順序一致性 ===> 即客戶端的更新將按發送順序執行
  • 原子性 ===> 即更新要麼成功要麼失敗,沒有中間狀態
  • 統一視圖 ===> 無論連接到哪個服務器,客戶端都將看到相同的服務視圖,即集羣內各節點對外展示的視圖統一不會有偏差
  • 可靠性 ===> 節點更新以後在下次操作它之前,該節點的數據不會發生變更
  • 及時性 ===> 集羣對外提供的客戶視圖保證在特定時間範圍內是最新的,可以理解成最終一致性,某個節點發生編號後會在特定時間內同步到集羣其他節點,這也呼應了統一視圖的特徵

3、常用命令

  • create [-s] [-e] path data
    -s 可選,表示創建的是序列節點,會給節點編號,可以在分佈式集羣環境下保證向同一個節點寫入數據的安全性(不被覆蓋)
    -e 可選,表示創建的是臨時節點
    path 必填,表示期望創建的節點路徑
    data 必填,表示期望存儲的數據,需要注意的是如果不用存數據該參數也不可缺省,可用""代替
  • get path
    獲取path路徑下的子節點信息
  • set path data
    設置path下存儲的值
  • delete path
    刪除path
  • sync path
    獲取path下集羣一致性達成後的最終數據,即如果請求的是非leader節點需同步向leader請求數據

二、ZK的集羣

zk是主從複製集羣,一個leader多個follower,只有leader能寫,其餘節點只提供讀功能,但是客戶端是可以連接集羣中任意節點的,當連接的是leader則直接寫,當連接的是follower則會被轉發到leader進行寫操作;zk集羣分爲兩種狀態,一種爲leader存活的可用狀態,另一種爲leader掛了的不可用狀態(無主);當集羣處於不可用狀態即leader下線時,分爲兩種情況,一種是剩餘存活節點的個數滿足過半選舉條件,此時會進行選主操作,過半通過即產生新的leader集羣恢復成可用狀態;另一種是剩餘存活節點數不滿足過半選舉條件,如leader掛了後集羣只剩兩臺機子了,這樣會出現腦裂問題,會導致選主失敗整個集羣仍會處於不可用狀態。需要注意的是第二種選主失敗集羣不可用的情況下,只是集羣對外不可用,對應存活實例的進程仍然存在,直到有新的服務上線滿足選主條件,從而使集羣快速恢復到可用狀態;下面通過圖示直觀展現:

集羣間數據同步問題

zk集羣由leader負責數據的增改操作,那麼leader的數據同步到集羣各節點是如何做到數據一致性的呢?zk採用的是最終一致性策略,通過ZAB協議實現,下面介紹ZAB協議

  • ZAB(原子廣播協議)
    ZAB是zk特有的一致性協議,並非分佈式通用的一致性協議,其基於Paxos演變而來;leader會爲每個follower分配一個FIFO的隊列,當leader接收到寫請求時,會爲寫入節點分配Zxid,同時將其放入隊列;follower按序從隊列中取出對應信息向自身的磁盤寫日誌成功後向leader回一個ack;當leader收到ack的個數大於集羣一半時即認爲消息確認成功,執行commit操作;並向各follower發起將數據寫到內存的操作,至此寫入操作完成;

總結:ZAB協議隊列和廣播以及兩階段提交來實現數據同步。通過隊列的FIFO特性以及兩階段提交保證了數據同步的原子性;
通過廣播給各個follower集羣並且不要求每個follower都同步成功(過半)保證了集羣間數據同步的高效性;
leader維護的隊列也爲最終一致性的策略提供了保證,leader會將所有的寫請求都放入隊列,follower按順序消費最終必然會與leader保持數據一致

集羣是如何選主的

當leader掛了後,集羣中任意節點發現後都會進行選主投票,只要有一個節點觸發投票那麼集羣中每個節點都會被動參與投票,因爲集羣各節點是互相連通的;zk集羣第一次啓動誰的ID大誰就是leader,後續集羣出了問題重啓的話,則誰的數據完整(Zxid大)誰是leader,如果保留的數據一樣大則再比較節點自身的myId;

補充
Zxid指的是當前節點的事物id,數值越大表示該節點的數據同步情況越完整;myid指的是在創建zk集羣的時候,我們給它配置的值

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章