ZooKeeper 技術原理

ZooKeeper 簡介

ZooKeeper 概述:

ZooKeeper 是一個分佈式的,開放源碼的分佈式應用程序協調服務,是 Google 的 Chubby 一個開源的實現,它是集羣的管理者,監視着集羣中各個節點的狀態根據節點提交的反饋進行下一步合理操作。最終,將簡單易用的接口和性能高效、功能穩定的系統提供給用戶。

ZooKeeper 分佈式服務框架主要是用來解決分佈式應用中經常遇到的一些數據管理問題,提供分佈式、高可用性的協調服務能力。

安全模式下 ZooKeeper 依賴於 Kerberos 和 L 搭配 Server 進行安全認證,非安全模式則不依賴與 Kerberos 與 Ldap。ZooKeeper 作爲底層組件廣泛被上層組件使用並依賴,如 Kafka,HDFS,HBase,Storm 等。

ZooKeeper 提供什麼?

  1. 文件系統

  2. 通知機制:客戶端註冊監聽它關心的目錄節點,當目錄節點發生變化(數據改變、被刪除、子目錄節點增加刪除)時,zookeeper 會通知客戶端。

  3. ZooKeeper 文件系統

    每個子目錄項如 NameService 都被稱作爲 znode,和文件系統一樣,我們能夠自由的增加、刪除 znode,在一個 znode 下增加、刪除子 znode,唯一的不同在於 znode 是可以存儲數據的。

有四種類型的 znode:

  1. PERSISTENT - 持久化目錄節點

    客戶端與 zookeeper 斷開連接後,該節點依舊存在 。

  2. PERSISTENT_SEQUENTIAL - 持久化順序編號目錄節點

    客戶端與 zookeeper 斷開連接後,該節點依舊存在,只是 Zookeeper 給該節點名稱進行順序編號 。

  3. EPHEMERAL - 臨時目錄節點

    客戶端與 zookeeper 斷開連接後,該節點被刪除 。

  4. EPHEMERAL_SEQUENTIAL - 臨時順序編號目錄節點

    客戶端與 zookeeper 斷開連接後,該節點被刪除,只是 Zookeeper 給該節點名稱進行順序編號 。

ZooKeeper 做什麼?

  1. 命名服務

  2. 配置管理

  3. 集羣管理

  4. 分佈式鎖

  5. 隊列管理

Zookeeper 命名服務

在 zookeeper 的文件系統裏創建一個目錄,即有唯一的 path。在我們使用 tborg 無法確定上游程序的部署機器時即可與下游程序約定好 path,通過 path 即能互相探索發現。

Zookeeper 的配置管理

程序總是需要配置的,如果程序分散部署在多臺機器上,要逐個改變配置就變得困難。現在把這些配置全部放到 zookeeper 上去,保存在 Zookeeper 的某個目錄節點中,然後所有相關應用程序對這個目錄節點進行監聽,一旦配置信息發生變化,每個應用程序就會收到 Zookeeper 的通知,然後從 Zookeeper 獲取新的配置信息應用到系統中就好

Zookeeper 集羣管理

所謂集羣管理無在乎兩點:是否有機器退出和加入、選舉 master。

對於第一點,所有機器約定在父目錄 GroupMembers 下創建臨時目錄節點,然後監聽父目錄節點的子節點變化消息。一旦有機器掛掉,該機器與 zookeeper 的連接斷開,其所創建的臨時目錄節點被刪除,所有其他機器都收到通知:某個兄弟目錄被刪除,於是,所有人都知道:它上船了。

新機器加入也是類似,所有機器收到通知:新兄弟目錄加入,highcount 又有了,對於第二點,我們稍微改變一下,所有機器創建臨時順序編號目錄節點,每次選取編號最小的機器作爲 master 就好。

Zookeeper 分佈式鎖

有了 zookeeper 的一致性文件系統,鎖的問題變得容易。鎖服務可以分爲兩類,一個是保持獨佔,另一個是控制時序。

對於第一類,我們將 zookeeper 上的一個 znode 看作是一把鎖,通過 createznode 的方式來實現。所有客戶端都去創建 /distribute_lock 節點,最終成功創建的那個客戶端也即擁有了這把鎖。用完刪除掉自己創建的 distribute_lock 節點就釋放出鎖。

對於第二類, /distribute_lock 已經預先存在,所有客戶端在它下面創建臨時順序編號目錄節點,和選 master 一樣,編號最小的獲得鎖,用完刪除,依次方便。

Zookeeper 隊列管理

兩種類型的隊列:

1、同步隊列,當一個隊列的成員都聚齊時,這個隊列纔可用,否則一直等待所有成員到達。

2、隊列按照 FIFO 方式進行入隊和出隊操作。

第一類,在約定目錄下創建臨時目錄節點,監聽節點數目是否是我們要求的數目。

第二類,和分佈式鎖服務中的控制時序場景基本原理一致,入列有編號,出列按編號。

ZooKeeper 在 FusionInsight 中的位置:

位置

圖:ZooKeeper 在 FusionInsight 中的位置

ZooKeeper 基於開源 Apache ZooKeeper 作爲底層組件爲上層組件提供服務,主要用於解決分佈式應用中經常遇到的一些數據管理問題。

ZooKeeper 系統架構

ZooKeeper 角色描述:

描述

ZooKeeper 服務架構 - 模型:

架構

圖:ZooKeeper 服務架構

圖:節點分佈命名

  1. 分層命名空間。

  2. 每個命名空間的節點都叫做 znode。

  3. 每個 znode 被路徑區分(如:/app1)。

  4. znode 節點類型 - 永久節點和臨時節點。

  5. 臨時節點不能有子節點。

  6. 每個 znode 節點有數據,也可以選擇有子節點。

  7. znode 不能被重命名

  8. 可以給 znode 增加或刪除 watchers。

ZooKeeper 分佈式與數據複製:

Zookeeper 作爲一個集羣提供一致的數據服務,自然,它要在所有機器間做數據複製。數據複製的好處:

  1. 容錯:一個節點出錯,不致於讓整個系統停止工作,別的節點可以接管它的工作;

  2. 提高系統的擴展能力 :把負載分佈到多個節點上,或者增加節點來提高系統的負載能力;

  3. 提高性能:讓客戶端本地訪問就近的節點,提高用戶訪問速度。

從客戶端讀寫訪問的透明度來看,數據複製集羣系統分下面兩種:

  1. 寫主 (WriteMaster) :對數據的修改提交給指定的節點。讀無此限制,可以讀取任何一個節點。這種情況下客戶端需要對讀與寫進行區別,俗稱讀寫分離;

  2. 寫任意 (Write Any):對數據的修改可提交給任意的節點,跟讀一樣。這種情況下,客戶端對集羣節點的角色與變化透明。

對 zookeeper 來說,它採用的方式是寫任意。通過增加機器,它的讀吞吐能力和響應能力擴展性非常好,而寫,隨着機器的增多吞吐能力肯定下降(這也是它建立 observer 的原因),而響應能力則取決於具體實現方式,是延遲複製保持最終一致性,還是立即複製快速響應。

ZooKeeper 的工作原理:

Zookeeper 的核心是原子廣播,這個機制保證了各個 Server 之間的同步。實現這個機制的協議叫做 Zab 協議。Zab 協議有兩種模式,它們分別是恢復模式(選主)和廣播模式(同步)。當服務啓動或者在領導者崩潰後,Zab 就進入了恢復模式,當領導者被選舉出來,且大多數 Server 完成了和 leader 的狀態同步以後,恢復模式就結束了。狀態同步保證了 leader 和 Server 具有相同的系統狀態。

爲了保證事務的順序一致性,zookeeper 採用了遞增的事務 id 號(zxid)來標識事務。所有的提議(proposal)都在被提出的時候加上了 zxid。實現中 zxid 是一個 64 位的數字,它高 32 位是 epoch 用來標識 leader 關係是否改變,每次一個 leader 被選出來,它都會有一個新的 epoch,標識當前屬於那個 leader 的統治時期。低 32 位用於遞增計數。

容災能力:

一般情況下,ZooKeeper 能夠完成選舉即能夠正常對外提供服務。ZooKeeper 選舉時,當某個實例獲得半數以上的票數時,則變爲 Leader。

對於 n 個示例,n 可能爲技術或偶數:

由此可見,2x+1 個節點與 2x+2 個節點的容災能力相同(3 個與 4 個相同,5 個與 6 個相同…), 而考慮到選舉以及完成寫操作的速度與節點數的相關性,建議 ZooKeeper 部署奇數個節點。

ZooKeeper 關鍵特性介紹

關鍵特性:

讀特性:

讀特性

圖:讀特性

由 ZooKeeper 的一致性可知,客戶端無論連接哪個 server,獲取的均是同一個視圖。所以,讀操作可在客戶端與任意節點間完成。

寫特性:

寫特性

圖:寫特性

客戶端可以向任意一個 Server 提出寫的請求,然後這個 server 會將這個請求發送給 ZooKeeper 的 leader,Leader 在獲取寫請求以後,會向所有節點發送這條寫的請求,詢問其他節點是否可以執行這個寫的操作。Follower 節點會根據自身的情況給出反饋信息,Leader 根據收到的反饋信息,如果同意寫的信息超過半數,那麼就執行寫操作。如果同意寫的票數少於半數,那麼就不執行寫操作。如果要執行寫操作, Leader 最後會將投票結果反饋給各個 Follower,然後完成寫的操作,每個 Follower 節點會同步 Leader 節點的數據。最後整個寫的操作就完成了。

ACL(訪問控制列表):

ACL 可以控制訪問 ZooKeeper 的節點,只能應用於特定的 znode 上,而不能應用於該 znode 的所有子節點上。設置 ACL 的命令爲:setAcl /znode scheme : id : perm。

Scheme 爲認證方式,ZooKeeper 內置了 4 種方式:

  1. world: 一個單獨的 ID,表示任何人都可以訪問。

  2. auth:不使用 ID,只有認證的用戶可以訪問。

  3. digest:使用 username:passwrod 生成 MD5 哈希值作爲認證 ID。

  4. IP:使用客戶端主機 IP 地址來進行認證。

id:用來認證的字段,用來判斷認證信息是否合法,不同的 scheme 的認證方式不同。

Perm:即 Permission,通過 Acl 認證的用戶對節點可擁有的操作權限。

日誌增強:

Ephemeral node(臨時節點)在 session 過期之後就會被系統刪除。在審計日誌中添加 Ephemeral node 被刪除的審計日誌,以便了解當時 Ephemeral node 的狀態信息。

ZooKeeper 客戶端常用命令使用:

ZooKeeper 與其他組件的關係

ZooKeeper 和 Storm Nimbus HA 的配合關係:

Nimbus

圖:ZooKeeper 和 Storm Nimbus HA 的配合關係

Storm Nimbus 利用 ZooKeeper 來選舉主備。

ZooKeeper 提供了以下兩種能力:

  1. 分佈式鎖服務:

    多個 Nimbus 進程都會嘗試去 Zookeeper 創建對應的節點,該節點只能被一個 Nimbus 進程創建成功,創建成功的 Nimbus 進程成爲主 Nimbus。

  2. 時間偵聽機制–watcher:

    備 Nimbus 偵聽對應的 ZooKeeper 節點。主 Nimbus 進程宕掉之後,該節點會被刪除,那麼備 Nimbus 就可以接受到相應的消息。

ZooKeeper 和 HDFS 的配合關係:

HDFS

圖:ZooKeeper 和 HDFS 的關係

ZKFC(ZooKeeper Failover Controller) 作爲一個 ZooKeeper 集羣的客戶端,用來監控 NameNode 的狀態信息。ZKFC 進程僅在部署了 NameNode 的節點中存在。HDFS NameNode 的 Active 和 Standby 節點均部署有 ZKFC 進程:

ZooKeeper 和 YARN 的配合關係:

YARN

圖:ZooKeeper 和 YARN 的配置關係

在系統啓動時,ResourceManager 會嘗試把選舉信息寫入 Zookeeper,第一個成功寫入 Zookeeper 的 ResourceManager 被選舉爲 Active ResourceManager,另一個爲 Standby ResourceManager。Standby ResourceManager 定時去 ZooKeeper 監控 Active ResourceManager 選舉信息。

Active ResourceManager 還會在 ZooKeeper 中創建 Statestore 目錄,存儲 Application 相關信息。當 Active ResourceManager 產生故障時,Standby ResourceManager 會從 Statestore 目錄獲取 Application 相關信息,恢復數據並升爲 Active。

ZooKeeper 和 HBase 的配合關係:

HBase

圖:ZooKeeper 和 HBase 的關係

HRegionServer 把自己以 Ephemeral 方式註冊到 Zookeeper 中。其中 ZooKeeper 存儲 HBase 的如下信息:HBase 元數據、HMaster 地址。

HMaster 通過 ZooKeeper 隨時感知各個 HRegionServer 的健康狀況,以便進行控制管理。

HBase 也可以部署多對 HMaster,類似 HDFS NameNode,當 HMaster 主節點出現故障時,HMaster 備用節點會通過 ZooKeeper 獲取主 HMaster 存儲的整個 HBase 集羣狀態信息。即通過 ZooKeeper 實現避免 HBase 單點故障問題。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/wwzmct_STT2VL0bsb-l_jg