您好,登錄后才能下訂單哦!
一 .Zookeeper功能簡介
ZooKeeper 是一個開源的分布式協調服務,由雅虎創建,是 Google Chubby 的開源實現。
分布式應用程序可以基于 ZooKeeper 實現諸如數據發布/訂閱、負載均衡、命名服務、分布式協
調/通知、集群管理、Master 選舉、配置維護,名字服務、分布式同步、分布式鎖和分布式隊列
等功能。
二 . ZooKeeper基本概念
本節將介紹 ZooKeeper 的幾個核心概念
因此有必要預先了解這些概念。
集群角色
一個 ZooKeeper 集群同一時刻只會有一個 Leader,其他都是 Follower 或 Observer。
ZooKeeper 配置很簡單,每個節點的配置文件(zoo.cfg)都是一樣的,只有 myid 文件不一樣。myid 的值必須是 zoo.cfg中server.{數值} 的{數值}部分。
zoo.cfg配置文件示例
在裝有 ZooKeeper 的機器的終端執行 zookeeper-server status 可以看當前節點的
ZooKeeper是什么角色(Leader or Follower)。
ZooKeeper 默認只有 Leader 和 Follower 兩種角色,沒有 Observer 角色。為了使用 Observer 模式,在任何想變成Observer的節點的配置文件中加入:peerType=observer 并在所有 server 的配置文件中,配置成 observer 模式的 server 的那行配置追加 :observer
2 . 節點讀寫服務分工
1.ZooKeeper 集群的所有機器通過一個 Leader 選舉過程來選定一臺被稱為『Leader』
的機器,Leader服務器為客戶端提供讀和寫服務。
2.Follower 和 Observer 都能提供讀服務,不能提供寫服務。兩者唯一的區別在于,
Observer機器不參與 Leader 選舉過程,也不參與寫操作的『過半寫成功』策略,因
此 Observer 可以在不影響寫性能的情況下提升集群的讀性能。
3 . Session
Session 是指客戶端會話,在講解客戶端會話之前,我們先來了解下客戶端連接。在
ZooKeeper 中,一個客戶端連接是指客戶端和 ZooKeeper 服務器之間的TCP長連接。
ZooKeeper 對外的服務端口默認是2181,客戶端啟動時,首先會與服務器建立一個TCP
連接,從第一次連接建立開始,客戶端會話的生命周期也開始了,通過這個連接,客戶端能夠通
過心跳檢測和服務器保持有效的會話,也能夠向 ZooKeeper 服務器發送請求并接受響應,同
時還能通過該連接接收來自服務器的 Watch 事件通知。
Session 的 SessionTimeout 值用來設置一個客戶端會話的超時時間。當由于服務器
壓力太大、網絡故障或是客戶端主動斷開連接等各種原因導致客戶端連接斷開時,只要在
SessionTimeout 規定的時間內能夠重新連接上集群中任意一臺服務器,那么之前創建的會話
仍然有效。
4 . 數據節點
zookeeper的結構其實就是一個樹形結構,leader就相當于其中的根結點,其它節點就相當于
follow節點,每個節點都保留自己的內容。
zookeeper的節點分兩類:持久節點和臨時節點
- 持久節點:
所謂持久節點是指一旦這個 樹形結構上被創建了,除非主動進行對樹節點的移除操
作,否則這個 節點將一直保存在 ZooKeeper 上。
- 臨時節點:
臨時節點的生命周期跟客戶端會話綁定,一旦客戶端會話失效,那么這個客戶端創
建的所有臨時節點都會被移除。
5 . 狀態信息
每個 節點除了存儲數據內容之外,還存儲了 節點本身的一些狀態信息。用 get 命令可以
同時獲得某個 節點的內容和狀態信息
在 ZooKeeper 中,version 屬性是用來實現樂觀鎖機制中的『寫入校驗』的(保證分布
式數據原子性操作)。
6 .事物操作
在ZooKeeper中,能改變ZooKeeper服務器狀態的操作稱為事務操作。一般包括數據節點
創建與刪除、數據內容更新和客戶端會話創建與失效等操作。對應每一個事務請求,ZooKeeper
都會為其分配一個全局唯一的事務ID,用 ZXID 表示,通常是一個64位的數字。每一個 ZXID
對應一次更新操作,從這些 ZXID 中可以間接地識別出 ZooKeeper 處理這些事務操作請求的
全局順序。
7 .Watcher(事件監聽器)
是 ZooKeeper 中一個很重要的特性。ZooKeeper允許用戶在指定節點上注冊一些 Watcher,
并且在一些特定事件觸發的時候,ZooKeeper 服務端會將事件通知到感興趣的客戶端上去。該
機制是 ZooKeeper 實現分布式協調服務的重要特性。
三 .ZooKeeper應用的典型場景
ZooKeeper 是一個高可用的分布式數據管理與協調框架。基于對ZAB算法的實現,該框架
能夠很好地保證分布式環境中數據的一致性。也是基于這樣的特性,使得 ZooKeeper 成為了
解決分布式一致性問題的利器。
1 . 數據發布與訂閱(配置中心)
數據發布與訂閱,即所謂的配置中心,顧名思義就是發布者將數據發布到 ZooKeeper 節點上,
供訂閱者進行數據訂閱,進而達到動態獲取數據的目的,實現配置信息的集中式管理和動態更新。
對于:數據量通常比較小。數據內容在運行時動態變化。集群中各機器共享,配置一致。
這樣的全局配置信息就可以發布到 ZooKeeper上,讓客戶端(集群的機器)去訂閱該消息。
發布/訂閱系統一般有兩種設計模式,分別是推(Push)和拉(Pull)模式。
- 推模式
服務端主動將數據更新發送給所有訂閱的客戶端
- 拉模式
客戶端主動發起請求來獲取最新數據,通常客戶端都采用定時輪詢拉取的方式
ZooKeeper 采用的是推拉相結合的方式:
客戶端想服務端注冊自己需要關注的節點,一旦該節點的數據發生變更,那么服務端就會向相應
的客戶端發送Watcher事件通知,客戶端接收到這個消息通知后,需要主動到服務端獲取最新的數據
2 . 命名服務
命名服務也是分布式系統中比較常見的一類場景。在分布式系統中,通過使用命名服務,客戶端
應用能夠根據指定名字來獲取資源或服務的地址,提供者等信息。被命名的實體通常可以是集群中的
機器,提供的服務,遠程對象等等——這些我們都可以統稱他們為名字。
其中較為常見的就是一些分布式服務框架(如RPC)中的服務地址列表。通過在ZooKeepr里
創建順序節點,能夠很容易創建一個全局唯一的路徑,這個路徑就可以作為一個名字。
ZooKeeper 的命名服務即生成全局唯一的ID。
3 . 分布式協調服務/通知
ZooKeeper 中特有 Watcher 注冊與異步通知機制,能夠很好的實現分布式環境下不同機器,
甚至不同系統之間的通知與協調,從而實現對數據變更的實時處理。使用方法通常是不同的客戶端
如果 機器節點 發生了變化,那么所有訂閱的客戶端都能夠接收到相應的Watcher通知,并做出相應
的處理。
ZooKeeper的分布式協調/通知,是一種通用的分布式系統機器間的通信方式。
4 . Master選舉
Master 選舉可以說是 ZooKeeper 最典型的應用場景了。比如 HDFS 中 Active NameNode 的選舉、YARN 中 Active ResourceManager 的選舉和 HBase 中 Active HMaster 的選舉等。
針對 Master 選舉的需求,通常情況下,我們可以選擇常見的關系型數據庫中的主鍵特性來
實現:希望成為 Master 的機器都向數據庫中插入一條相同主鍵ID的記錄,數據庫會幫我們進行
主鍵沖突檢查,也就是說,只有一臺機器能插入成功——那么,我們就認為向數據庫中成功插入數據
的客戶端機器成為Master。
依靠關系型數據庫的主鍵特性確實能夠很好地保證在集群中選舉出唯一的一個Master。
但是,如果當前選舉出的 Master 掛了,那么該如何處理?誰來告訴我 Master 掛了呢?
顯然,關系型數據庫無法通知我們這個事件。但是,ZooKeeper 可以做到!
利用 ZooKeepr 的強一致性,能夠很好地保證在分布式高并發情況下節點的創建一定能夠
保證全局唯一性,即 ZooKeeper 將會保證客戶端無法創建一個已經存在的 數據單元節點。
也就是說,如果同時有多個客戶端請求創建同一個臨時節點,那么最終一定只有一個客戶端
請求能夠創建成功。利用這個特性,就能很容易地在分布式環境中進行 Master 選舉了。
成功創建該節點的客戶端所在的機器就成為了 Master。同時,其他沒有成功創建該節點的
客戶端,都會在該節點上注冊一個子節點變更的 Watcher,用于監控當前 Master 機器是否存
活,一旦發現當前的Master掛了,那么其他客戶端將會重新進行 Master 選舉。
這樣就實現了 Master 的動態選舉。
5 . 分布式鎖
分布式鎖是控制分布式系統之間同步訪問共享資源的一種方式
分布式鎖又分為排他鎖和共享鎖兩種
排它鎖
ZooKeeper如何實現排它鎖?
定義鎖
ZooKeeper 上的一個 機器節點 可以表示一個鎖
獲得鎖
把ZooKeeper上的一個節點看作是一個鎖,獲得鎖就通過創建臨時節點的方式來實現。
ZooKeeper 會保證在所有客戶端中,最終只有一個客戶端能夠創建成功,那么就可以
認為該客戶端獲得了鎖。同時,所有沒有獲取到鎖的客戶端就需要到/exclusive_lock
節點上注冊一個子節點變更的Watcher監聽,以便實時監聽到lock節點的變更情況。
釋放鎖
因為鎖是一個臨時節點,釋放鎖有兩種方式
當前獲得鎖的客戶端機器發生宕機或重啟,那么該臨時節點就會被刪除,釋放鎖
正常執行完業務邏輯后,客戶端就會主動將自己創建的臨時節點刪除,釋放鎖。
無論在什么情況下移除了lock節點,ZooKeeper 都會通知所有在 /exclusive_lock 節點上注冊了節點變更 Watcher 監聽的客戶端。這些客戶端在接收到通知后,再次重新發起分布式鎖獲取,即重復『獲取鎖』過程。
共享鎖
共享鎖在同一個進程中很容易實現,但是在跨進程或者在不同 Server 之間就不好實現了。Zookeeper 卻很容易實現這個功能,實現方式也是需要獲得鎖的 Server 創建一個 EPHEMERAL_SEQUENTIAL 目錄節點,然后調用 getChildren方法獲取當前的目錄節點列表中最小的目錄節點是不是就是自己創建的目錄節點,如果正是自己創建的,那么它就獲得了這個鎖,如果不是那么它就調用 exists(String path, boolean watch) 方法并監控 Zookeeper 上目錄節點列表的變化,一直到自己創建的節點是列表中最小編號的目錄節點,從而獲得鎖,釋放鎖很簡單,只要刪除前面它自己所創建的目錄節點就行了。
總結
本文介紹的 Zookeeper 的基本知識,以及介紹了幾個典型的應用場景。這些都是 Zookeeper
的基本功能,最重要的是 Zoopkeeper 提供了一套很好的分布式集群管理的機制,就是它這種基于
層次型的目錄樹的數據結構,并對樹中的節點進行有效管理,從而可以設計出多種多樣的分布式的數
據管理模型,而不僅僅局限于上面提到的幾個常用應用場景
喜歡這篇文章的話記得給我點個關注哦,每天都會分享java有關的文章
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。