您好,登錄后才能下訂單哦!
本文講述了ZooKeeper的原理,小編覺得挺不錯,分享給大家供大家參考,具體如下:
前言
ZooKeeper 是一個開源的分布式協(xié)調(diào)服務(wù),由雅虎創(chuàng)建,是 Google Chubby 的開源實現(xiàn)。分布式應(yīng)用程序可以基于 ZooKeeper 實現(xiàn)諸如數(shù)據(jù)發(fā)布/訂閱、負(fù)載均衡、命名服務(wù)、分布式協(xié)調(diào)/通知、集群管理、Master 選舉、分布式鎖和分布式隊列等功能。
1、簡介
ZooKeeper 是一個開源的分布式協(xié)調(diào)服務(wù),由雅虎創(chuàng)建,是 Google Chubby 的開源實現(xiàn)。分布式應(yīng)用程序可以基于 ZooKeeper 實現(xiàn)諸如數(shù)據(jù)發(fā)布/訂閱、負(fù)載均衡、命名服務(wù)、分布式協(xié)調(diào)/通知、集群管理、Master 選舉、分布式鎖和分布式隊列等功能。
2、基本概念
本節(jié)將介紹 ZooKeeper 的幾個核心概念。這些概念貫穿于之后對 ZooKeeper 更深入的講解,因此有必要預(yù)先了解這些概念。
2.1 集群角色
在 ZooKeeper 中,有三種角色:
Leader
Follower
Observer
一個 ZooKeeper 集群同一時刻只會有一個 Leader,其他都是 Follower 或 Observer。
ZooKeeper 配置很簡單,每個節(jié)點的配置文件(zoo.cfg)都是一樣的,只有 myid 文件不一樣。myid 的值必須是 zoo.cfg中server.{數(shù)值} 的{數(shù)值}部分。
zoo.cfg 文件內(nèi)容示例:
ZooKeeper
在裝有 ZooKeeper 的機器的終端執(zhí)行 zookeeper-server status 可以看當(dāng)前節(jié)點的 ZooKeeper 是什么角色(Leader or Follower)。
ZooKeeper
如上,node-20-104 是 Leader,node-20-103 是 follower。
ZooKeeper 默認(rèn)只有 Leader 和 Follower 兩種角色,沒有 Observer 角色。為了使用 Observer 模式,在任何想變成Observer的節(jié)點的配置文件中加入:peerType=observer 并在所有 server 的配置文件中,配置成 observer 模式的 server 的那行配置追加 :observer,例如:
server.1:localhost:2888:3888:observer
ZooKeeper 集群的所有機器通過一個 Leader 選舉過程來選定一臺被稱為『Leader』的機器,Leader服務(wù)器為客戶端提供讀和寫服務(wù)。
Follower 和 Observer 都能提供讀服務(wù),不能提供寫服務(wù)。兩者唯一的區(qū)別在于,Observer 機器不參與 Leader 選舉過程,也不參與寫操作的『過半寫成功』策略,因此 Observer 可以在不影響寫性能的情況下提升集群的讀性能。
2.2 會話(Session)
Session 是指客戶端會話,在講解客戶端會話之前,我們先來了解下客戶端連接。在 ZooKeeper 中,一個客戶端連接是指客戶端和 ZooKeeper 服務(wù)器之間的TCP長連接。
ZooKeeper 對外的服務(wù)端口默認(rèn)是2181,客戶端啟動時,首先會與服務(wù)器建立一個TCP連接,從第一次連接建立開始,客戶端會話的生命周期也開始了,通過這個連接,客戶端能夠通過心跳檢測和服務(wù)器保持有效的會話,也能夠向 ZooKeeper 服務(wù)器發(fā)送請求并接受響應(yīng),同時還能通過該連接接收來自服務(wù)器的 Watch 事件通知。
Session 的 SessionTimeout 值用來設(shè)置一個客戶端會話的超時時間。當(dāng)由于服務(wù)器壓力太大、網(wǎng)絡(luò)故障或是客戶端主動斷開連接等各種原因?qū)е驴蛻舳诉B接斷開時,只要在 SessionTimeout 規(guī)定的時間內(nèi)能夠重新連接上集群中任意一臺服務(wù)器,那么之前創(chuàng)建的會話仍然有效。
2.3 數(shù)據(jù)節(jié)點(ZNode)
在談到分布式的時候,一般『節(jié)點』指的是組成集群的每一臺機器。而ZooKeeper 中的數(shù)據(jù)節(jié)點是指數(shù)據(jù)模型中的數(shù)據(jù)單元,稱為 ZNode。ZooKeeper 將所有數(shù)據(jù)存儲在內(nèi)存中,數(shù)據(jù)模型是一棵樹(ZNode Tree),由斜杠(/)進(jìn)行分割的路徑,就是一個ZNode,如 /hbase/master,其中 hbase 和 master 都是 ZNode。每個 ZNode 上都會保存自己的數(shù)據(jù)內(nèi)容,同時會保存一系列屬性信息。
注:
這里的 ZNode 可以理解成既是Unix里的文件,又是Unix里的目錄。因為每個 ZNode 不僅本身可以寫數(shù)據(jù)(相當(dāng)于Unix里的文件),還可以有下一級文件或目錄(相當(dāng)于Unix里的目錄)。
在 ZooKeeper 中,ZNode 可以分為持久節(jié)點和臨時節(jié)點兩類。
持久節(jié)點
所謂持久節(jié)點是指一旦這個 ZNode 被創(chuàng)建了,除非主動進(jìn)行 ZNode 的移除操作,否則這個 ZNode 將一直保存在ZooKeeper 上。
臨時節(jié)點
臨時節(jié)點的生命周期跟客戶端會話綁定,一旦客戶端會話失效,那么這個客戶端創(chuàng)建的所有臨時節(jié)點都會被移除。
另外,ZooKeeper 還允許用戶為每個節(jié)點添加一個特殊的屬性:SEQUENTIAL。一旦節(jié)點被標(biāo)記上這個屬性,那么在這個節(jié)點被創(chuàng)建的時候,ZooKeeper 就會自動在其節(jié)點后面追加上一個整型數(shù)字,這個整型數(shù)字是一個由父節(jié)點維護(hù)的自增數(shù)字。
2.4 版本
ZooKeeper 的每個 ZNode 上都會存儲數(shù)據(jù),對應(yīng)于每個 ZNode,ZooKeeper 都會為其維護(hù)一個叫作 Stat 的數(shù)據(jù)結(jié)構(gòu),Stat 中記錄了這個 ZNode 的三個數(shù)據(jù)版本,分別是 version(當(dāng)前ZNode的版本)、cversion(當(dāng)前ZNode子節(jié)點的版本)和 aversion(當(dāng)前 ZNode 的 ACL 版本)。
2.5 狀態(tài)信息
每個 ZNode 除了存儲數(shù)據(jù)內(nèi)容之外,還存儲了 ZNode 本身的一些狀態(tài)信息。用 get 命令可以同時獲得某個 ZNode 的內(nèi)容和狀態(tài)信息。如下:
ZooKeeper
在 ZooKeeper 中,version 屬性是用來實現(xiàn)樂觀鎖機制中的『寫入校驗』的(保證分布式數(shù)據(jù)原子性操作)。
2.6 事務(wù)操作
在ZooKeeper中,能改變ZooKeeper服務(wù)器狀態(tài)的操作稱為事務(wù)操作。一般包括數(shù)據(jù)節(jié)點創(chuàng)建與刪除、數(shù)據(jù)內(nèi)容更新和客戶端會話創(chuàng)建與失效等操作。對應(yīng)每一個事務(wù)請求,ZooKeeper 都會為其分配一個全局唯一的事務(wù)ID,用 ZXID 表示,通常是一個64位的數(shù)字。每一個 ZXID 對應(yīng)一次更新操作,從這些 ZXID 中可以間接地識別出 ZooKeeper 處理這些事務(wù)操作請求的全局順序。
2.7 Watcher
Watcher(事件監(jiān)聽器),是 ZooKeeper 中一個很重要的特性。ZooKeeper允許用戶在指定節(jié)點上注冊一些 Watcher,并且在一些特定事件觸發(fā)的時候,ZooKeeper 服務(wù)端會將事件通知到感興趣的客戶端上去。該機制是 ZooKeeper 實現(xiàn)分布式協(xié)調(diào)服務(wù)的重要特性。
2.8 ACL
ZooKeeper 采用 ACL(Access Control Lists)策略來進(jìn)行權(quán)限控制。ZooKeeper 定義了如下5種權(quán)限。
CREATE: 創(chuàng)建子節(jié)點的權(quán)限。
READ: 獲取節(jié)點數(shù)據(jù)和子節(jié)點列表的權(quán)限。
WRITE:更新節(jié)點數(shù)據(jù)的權(quán)限。
DELETE: 刪除子節(jié)點的權(quán)限。
ADMIN: 設(shè)置節(jié)點ACL的權(quán)限。
注意:CREATE 和 DELETE 都是針對子節(jié)點的權(quán)限控制。
3. ZooKeeper典型應(yīng)用場景
ZooKeeper 是一個高可用的分布式數(shù)據(jù)管理與協(xié)調(diào)框架。基于對ZAB算法的實現(xiàn),該框架能夠很好地保證分布式環(huán)境中數(shù)據(jù)的一致性。也是基于這樣的特性,使得 ZooKeeper 成為了解決分布式一致性問題的利器。
3.1 數(shù)據(jù)發(fā)布與訂閱(配置中心)
數(shù)據(jù)發(fā)布與訂閱,即所謂的配置中心,顧名思義就是發(fā)布者將數(shù)據(jù)發(fā)布到 ZooKeeper 節(jié)點上,供訂閱者進(jìn)行數(shù)據(jù)訂閱,進(jìn)而達(dá)到動態(tài)獲取數(shù)據(jù)的目的,實現(xiàn)配置信息的集中式管理和動態(tài)更新。
在我們平常的應(yīng)用系統(tǒng)開發(fā)中,經(jīng)常會碰到這樣的需求:系統(tǒng)中需要使用一些通用的配置信息,例如機器列表信息、數(shù)據(jù)庫配置信息等。這些全局配置信息通常具備以下3個特性。
數(shù)據(jù)量通常比較小。
數(shù)據(jù)內(nèi)容在運行時動態(tài)變化。
集群中各機器共享,配置一致。
對于這樣的全局配置信息就可以發(fā)布到 ZooKeeper上,讓客戶端(集群的機器)去訂閱該消息。
發(fā)布/訂閱系統(tǒng)一般有兩種設(shè)計模式,分別是推(Push)和拉(Pull)模式。
推:服務(wù)端主動將數(shù)據(jù)更新發(fā)送給所有訂閱的客戶端。
拉:客戶端主動發(fā)起請求來獲取最新數(shù)據(jù),通??蛻舳硕疾捎枚〞r輪詢拉取的方式。
ZooKeeper 采用的是推拉相結(jié)合的方式。如下:
客戶端想服務(wù)端注冊自己需要關(guān)注的節(jié)點,一旦該節(jié)點的數(shù)據(jù)發(fā)生變更,那么服務(wù)端就會向相應(yīng)的客戶端發(fā)送Watcher事件通知,客戶端接收到這個消息通知后,需要主動到服務(wù)端獲取最新的數(shù)據(jù)(推拉結(jié)合)。
3.2 命名服務(wù)(Naming Service)
命名服務(wù)也是分布式系統(tǒng)中比較常見的一類場景。在分布式系統(tǒng)中,通過使用命名服務(wù),客戶端應(yīng)用能夠根據(jù)指定名字來獲取資源或服務(wù)的地址,提供者等信息。被命名的實體通常可以是集群中的機器,提供的服務(wù),遠(yuǎn)程對象等等——這些我們都可以統(tǒng)稱他們?yōu)槊郑∟ame)。
其中較為常見的就是一些分布式服務(wù)框架(如RPC、RMI)中的服務(wù)地址列表。通過在ZooKeepr里創(chuàng)建順序節(jié)點,能夠很容易創(chuàng)建一個全局唯一的路徑,這個路徑就可以作為一個名字。
ZooKeeper 的命名服務(wù)即生成全局唯一的ID。
3.3 分布式協(xié)調(diào)/通知
ZooKeeper 中特有 Watcher 注冊與異步通知機制,能夠很好的實現(xiàn)分布式環(huán)境下不同機器,甚至不同系統(tǒng)之間的通知與協(xié)調(diào),從而實現(xiàn)對數(shù)據(jù)變更的實時處理。使用方法通常是不同的客戶端都對ZK上同一個 ZNode 進(jìn)行注冊,監(jiān)聽 ZNode 的變化(包括ZNode本身內(nèi)容及子節(jié)點的),如果 ZNode 發(fā)生了變化,那么所有訂閱的客戶端都能夠接收到相應(yīng)的Watcher通知,并做出相應(yīng)的處理。
ZK的分布式協(xié)調(diào)/通知,是一種通用的分布式系統(tǒng)機器間的通信方式。
3.3.1 心跳檢測
機器間的心跳檢測機制是指在分布式環(huán)境中,不同機器(或進(jìn)程)之間需要檢測到彼此是否在正常運行,例如A機器需要知道B機器是否正常運行。在傳統(tǒng)的開發(fā)中,我們通常是通過主機直接是否可以相互PING通來判斷,更復(fù)雜一點的話,則會通過在機器之間建立長連接,通過TCP連接固有的心跳檢測機制來實現(xiàn)上層機器的心跳檢測,這些都是非常常見的心跳檢測方法。
下面來看看如何使用ZK來實現(xiàn)分布式機器(進(jìn)程)間的心跳檢測。
基于ZK的臨時節(jié)點的特性,可以讓不同的進(jìn)程都在ZK的一個指定節(jié)點下創(chuàng)建臨時子節(jié)點,不同的進(jìn)程直接可以根據(jù)這個臨時子節(jié)點來判斷對應(yīng)的進(jìn)程是否存活。通過這種方式,檢測和被檢測系統(tǒng)直接并不需要直接相關(guān)聯(lián),而是通過ZK上的某個節(jié)點進(jìn)行關(guān)聯(lián),大大減少了系統(tǒng)耦合。
3.3.2 工作進(jìn)度匯報
在一個常見的任務(wù)分發(fā)系統(tǒng)中,通常任務(wù)被分發(fā)到不同的機器上執(zhí)行后,需要實時地將自己的任務(wù)執(zhí)行進(jìn)度匯報給分發(fā)系統(tǒng)。這個時候就可以通過ZK來實現(xiàn)。在ZK上選擇一個節(jié)點,每個任務(wù)客戶端都在這個節(jié)點下面創(chuàng)建臨時子節(jié)點,這樣便可以實現(xiàn)兩個功能:
通過判斷臨時節(jié)點是否存在來確定任務(wù)機器是否存活。
各個任務(wù)機器會實時地將自己的任務(wù)執(zhí)行進(jìn)度寫到這個臨時節(jié)點上去,以便中心系統(tǒng)能夠?qū)崟r地獲取到任務(wù)的執(zhí)行進(jìn)度。
3.4 Master選舉
Master 選舉可以說是 ZooKeeper 最典型的應(yīng)用場景了。比如 HDFS 中 Active NameNode 的選舉、YARN 中 Active ResourceManager 的選舉和 HBase 中 Active HMaster 的選舉等。
針對 Master 選舉的需求,通常情況下,我們可以選擇常見的關(guān)系型數(shù)據(jù)庫中的主鍵特性來實現(xiàn):希望成為 Master 的機器都向數(shù)據(jù)庫中插入一條相同主鍵ID的記錄,數(shù)據(jù)庫會幫我們進(jìn)行主鍵沖突檢查,也就是說,只有一臺機器能插入成功——那么,我們就認(rèn)為向數(shù)據(jù)庫中成功插入數(shù)據(jù)的客戶端機器成為Master。
依靠關(guān)系型數(shù)據(jù)庫的主鍵特性確實能夠很好地保證在集群中選舉出唯一的一個Master。
但是,如果當(dāng)前選舉出的 Master 掛了,那么該如何處理?誰來告訴我 Master 掛了呢?顯然,關(guān)系型數(shù)據(jù)庫無法通知我們這個事件。但是,ZooKeeper 可以做到!
利用 ZooKeepr 的強一致性,能夠很好地保證在分布式高并發(fā)情況下節(jié)點的創(chuàng)建一定能夠保證全局唯一性,即 ZooKeeper 將會保證客戶端無法創(chuàng)建一個已經(jīng)存在的 ZNode。
也就是說,如果同時有多個客戶端請求創(chuàng)建同一個臨時節(jié)點,那么最終一定只有一個客戶端請求能夠創(chuàng)建成功。利用這個特性,就能很容易地在分布式環(huán)境中進(jìn)行 Master 選舉了。
成功創(chuàng)建該節(jié)點的客戶端所在的機器就成為了 Master。同時,其他沒有成功創(chuàng)建該節(jié)點的客戶端,都會在該節(jié)點上注冊一個子節(jié)點變更的 Watcher,用于監(jiān)控當(dāng)前 Master 機器是否存活,一旦發(fā)現(xiàn)當(dāng)前的Master掛了,那么其他客戶端將會重新進(jìn)行 Master 選舉。
這樣就實現(xiàn)了 Master 的動態(tài)選舉。
3.5 分布式鎖
分布式鎖是控制分布式系統(tǒng)之間同步訪問共享資源的一種方式。
分布式鎖又分為排他鎖和共享鎖兩種。
3.5.1 排他鎖
排他鎖(Exclusive Locks,簡稱X鎖),又稱為寫鎖或獨占鎖。
如果事務(wù)T1對數(shù)據(jù)對象O1加上了排他鎖,那么在整個加鎖期間,只允許事務(wù)T1對O1進(jìn)行讀取和更新操作,其他任何事務(wù)都不能在對這個數(shù)據(jù)對象進(jìn)行任何類型的操作(不能再對該對象加鎖),直到T1釋放了排他鎖。
可以看出,排他鎖的核心是如何保證當(dāng)前只有一個事務(wù)獲得鎖,并且鎖被釋放后,所有正在等待獲取鎖的事務(wù)都能夠被通知到。
如何利用 ZooKeeper 實現(xiàn)排他鎖?
定義鎖
ZooKeeper 上的一個 ZNode 可以表示一個鎖。例如 /exclusive_lock/lock節(jié)點就可以被定義為一個鎖。
獲得鎖
如上所說,把ZooKeeper上的一個ZNode看作是一個鎖,獲得鎖就通過創(chuàng)建 ZNode 的方式來實現(xiàn)。所有客戶端都去 /exclusive_lock節(jié)點下創(chuàng)建臨時子節(jié)點 /exclusive_lock/lock。ZooKeeper 會保證在所有客戶端中,最終只有一個客戶端能夠創(chuàng)建成功,那么就可以認(rèn)為該客戶端獲得了鎖。同時,所有沒有獲取到鎖的客戶端就需要到/exclusive_lock節(jié)點上注冊一個子節(jié)點變更的Watcher監(jiān)聽,以便實時監(jiān)聽到lock節(jié)點的變更情況。
釋放鎖
因為 /exclusive_lock/lock 是一個臨時節(jié)點,因此在以下兩種情況下,都有可能釋放鎖。
當(dāng)前獲得鎖的客戶端機器發(fā)生宕機或重啟,那么該臨時節(jié)點就會被刪除,釋放鎖。
正常執(zhí)行完業(yè)務(wù)邏輯后,客戶端就會主動將自己創(chuàng)建的臨時節(jié)點刪除,釋放鎖。
無論在什么情況下移除了lock節(jié)點,ZooKeeper 都會通知所有在 /exclusive_lock 節(jié)點上注冊了節(jié)點變更 Watcher 監(jiān)聽的客戶端。這些客戶端在接收到通知后,再次重新發(fā)起分布式鎖獲取,即重復(fù)『獲取鎖』過程。
3.5.2 共享鎖
共享鎖(Shared Locks,簡稱S鎖),又稱為讀鎖。如果事務(wù)T1對數(shù)據(jù)對象O1加上了共享鎖,那么T1只能對O1進(jìn)行讀操作,其他事務(wù)也能同時對O1加共享鎖(不能是排他鎖),直到O1上的所有共享鎖都釋放后O1才能被加排他鎖。
總結(jié):可以多個事務(wù)同時獲得一個對象的共享鎖(同時讀),有共享鎖就不能再加排他鎖(因為排他鎖是寫鎖)
4、ZooKeeper在大型分布式系統(tǒng)中的應(yīng)用
前面已經(jīng)介紹了 ZooKeeper 的典型應(yīng)用場景。本節(jié)將以常見的大數(shù)據(jù)產(chǎn)品 Hadoop 和 HBase 為例來介紹 ZooKeeper 在其中的應(yīng)用,幫助大家更好地理解 ZooKeeper 的分布式應(yīng)用場景。
4.1 ZooKeeper在Hadoop中的應(yīng)用
在 Hadoop 中,ZooKeeper 主要用于實現(xiàn) HA(Hive Availability),包括 HDFS的 NamaNode 和 YARN 的 ResourceManager 的 HA。同時,在 YARN 中, ZooKeepr 還用來存儲應(yīng)用的運行狀態(tài)。
HDFS 的 NamaNode 和 YARN 的 ResourceManager 利用 ZooKeepr 實現(xiàn) HA 的原理是一樣的,所以本節(jié)以YARN為例來介紹。
ZooKeeper
從上圖可以看出,YARN主要由ResourceManager(RM)、NodeManager(NM)、ApplicationMaster(AM)和Container四部分組成。其中最核心的就是ResourceManager。
ResourceManager 負(fù)責(zé)集群中所有資源的統(tǒng)一管理和分配,同時接收來自各個節(jié)點(NodeManager)的資源匯報信息,并把這些信息按照一定的策略分配給各個應(yīng)用程序(Application Manager),其內(nèi)部維護(hù)了各個應(yīng)用程序的ApplicationMaster信息、NodeManager信息以及資源使用信息等。
為了實現(xiàn)HA,必須有多個ResourceManager并存(一般就兩個),并且只有一個ResourceManager處于Active狀態(tài),其他的則處于Standby狀態(tài),當(dāng)Active節(jié)點無法正常工作(如機器宕機或重啟)時,處于Standby的就會通過競爭選舉產(chǎn)生新的Active節(jié)點。
4.2 主備切換
下面我們就來看看YARN是如何實現(xiàn)多個ResourceManager之間的主備切換的。
1. 創(chuàng)建鎖節(jié)點
在 ZooKeeper 上會有一個/yarn-leader-election/appcluster-yarn的鎖節(jié)點,所有的 ResourceManager 在啟動的時候,都會去競爭寫一個Lock子節(jié)點:/yarn-leader-election/appcluster-yarn/ActiveBreadCrumb,該節(jié)點是臨時節(jié)點。
ZooKeepr 能夠為我們保證最終只有一個ResourceManager能夠創(chuàng)建成功。創(chuàng)建成功的那個 ResourceManager 就切換為 Active 狀態(tài),沒有成功的那些 ResourceManager 則切換為 Standby 狀態(tài)。
ZooKeeper
可以看到此時集群中 ResourceManager2 為 Active。
注冊 Watcher 監(jiān)聽
所有 Standby 狀態(tài)的 ResourceManager 都會向 /yarn-leader-election/appcluster-yarn/ActiveBreadCrumb 節(jié)點注冊一個節(jié)點變更的Watcher監(jiān)聽,利用臨時節(jié)點的特性,能夠快速感知到Active狀態(tài)的ResourceManager的運行情況。
主備切換
當(dāng)Active狀態(tài)的ResourceManager出現(xiàn)諸如宕機或重啟的異常情況時,其在ZooKeeper上連接的客戶端會話就會失效,因此/yarn-leader-election/appcluster-yarn/ActiveBreadCrumb節(jié)點就會被刪除。此時其余各個Standby狀態(tài)的ResourceManager就都會接收到來自ZooKeeper服務(wù)端的Watcher事件通知,然后會重復(fù)進(jìn)行步驟1的操作。
以上就是利用 ZooKeeper 來實現(xiàn) ResourceManager 的主備切換的過程,實現(xiàn)了 ResourceManager 的HA。
HDFS 中 NameNode 的 HA 的實現(xiàn)原理跟 YARN 中 ResourceManager 的 HA 的實現(xiàn)原理相同。其鎖節(jié)點為 /hadoop-ha/mycluster/ActiveBreadCrumb。
4.3 ResourceManager狀態(tài)存儲
在 ResourceManager 中,RMStateStore 能夠存儲一些 RM 的內(nèi)部狀態(tài)信息,包括 Application 以及它們的 Attempts 信息、Delegation Token 及 Version Information 等。需要注意的是,RMStateStore 中的絕大多數(shù)狀態(tài)信息都是不需要持久化存儲的,因為很容易從上下文信息中將其重構(gòu)出來,如資源的使用情況。在存儲的設(shè)計方案中,提供了三種可能的實現(xiàn),分別如下。
基于內(nèi)存實現(xiàn),一般是用于日常開發(fā)測試。
基于文件系統(tǒng)的實現(xiàn),如HDFS。
基于 ZooKeeper 實現(xiàn)。
由于這些狀態(tài)信息的數(shù)據(jù)量都不是很大,因此 Hadoop 官方建議基于 ZooKeeper 來實現(xiàn)狀態(tài)信息的存儲。在 ZooKeepr 上,ResourceManager 的狀態(tài)信息都被存儲在 /rmstore 這個根節(jié)點下面。
ZooKeeper
RMAppRoot 節(jié)點下存儲的是與各個 Application 相關(guān)的信息,RMDTSecretManagerRoot 存儲的是與安全相關(guān)的 Token 等信息。每個 Active 狀態(tài)的 ResourceManager 在初始化階段都會從 ZooKeeper 上讀取到這些狀態(tài)信息,并根據(jù)這些狀態(tài)信息繼續(xù)進(jìn)行相應(yīng)的處理。
4.4 小結(jié):
ZooKeepr 在 Hadoop 中的應(yīng)用主要有:
HDFS 中 NameNode 的 HA 和 YARN 中 ResourceManager 的 HA。
存儲 RMStateStore 狀態(tài)信息
5、ZooKeeper在HBase中的應(yīng)用
HBase 主要用 ZooKeeper 來實現(xiàn) HMaster 選舉與主備切換、系統(tǒng)容錯、RootRegion 管理、Region狀態(tài)管理和分布式
SplitWAL 任務(wù)管理等。
5.1 HMaster選舉與主備切換
HMaster選舉與主備切換的原理和HDFS中NameNode及YARN中ResourceManager的HA原理相同。
5.2 系統(tǒng)容錯
當(dāng) HBase 啟動時,每個 RegionServer 都會到 ZooKeeper 的/hbase/rs節(jié)點下創(chuàng)建一個信息節(jié)點(下文中,我們稱該節(jié)點為”rs狀態(tài)節(jié)點”),例如/hbase/rs/[Hostname],同時,HMaster 會對這個節(jié)點注冊監(jiān)聽。當(dāng)某個 RegionServer 掛掉的時候,ZooKeeper 會因為在一段時間內(nèi)無法接受其心跳(即 Session 失效),而刪除掉該 RegionServer 服務(wù)器對應(yīng)的 rs 狀態(tài)節(jié)點。
與此同時,HMaster 則會接收到 ZooKeeper 的 NodeDelete 通知,從而感知到某個節(jié)點斷開,并立即開始容錯工作。
HBase 為什么不直接讓 HMaster 來負(fù)責(zé) RegionServer 的監(jiān)控呢?如果 HMaster 直接通過心跳機制等來管理RegionServer的狀態(tài),隨著集群越來越大,HMaster 的管理負(fù)擔(dān)會越來越重,另外它自身也有掛掉的可能,因此數(shù)據(jù)還需要持久化。在這種情況下,ZooKeeper 就成了理想的選擇。
5.3 RootRegion管理
對應(yīng) HBase 集群來說,數(shù)據(jù)存儲的位置信息是記錄在元數(shù)據(jù) region,也就是 RootRegion 上的。每次客戶端發(fā)起新的請求,需要知道數(shù)據(jù)的位置,就會去查詢 RootRegion,而 RootRegion 自身位置則是記錄在 ZooKeeper 上的(默認(rèn)情況下,是記錄在 ZooKeeper 的/hbase/meta-region-server節(jié)點中)。
當(dāng) RootRegion 發(fā)生變化,比如 Region 的手工移動、重新負(fù)載均衡或 RootRegion 所在服務(wù)器發(fā)生了故障等是,就能夠通過 ZooKeeper 來感知到這一變化并做出一系列相應(yīng)的容災(zāi)措施,從而保證客戶端總是能夠拿到正確的 RootRegion 信息。
5.4 Region管理
HBase 里的 Region 會經(jīng)常發(fā)生變更,這些變更的原因來自于系統(tǒng)故障、負(fù)載均衡、配置修改、Region 分裂與合并等。一旦 Region 發(fā)生移動,它就會經(jīng)歷下線(offline)和重新上線(online)的過程。
在下線期間數(shù)據(jù)是不能被訪問的,并且 Region 的這個狀態(tài)變化必須讓全局知曉,否則可能會出現(xiàn)事務(wù)性的異常。
對于大的 HBase 集群來說,Region 的數(shù)量可能會多達(dá)十萬級別,甚至更多,這樣規(guī)模的 Region 狀態(tài)管理交給 ZooKeeper 來做也是一個很好的選擇。
5.5 分布式SplitWAL任務(wù)管理
當(dāng)某臺 RegionServer 服務(wù)器掛掉時,由于總有一部分新寫入的數(shù)據(jù)還沒有持久化到 HFile 中,因此在遷移該 RegionServer 的服務(wù)時,一個重要的工作就是從 WAL 中恢復(fù)這部分還在內(nèi)存中的數(shù)據(jù),而這部分工作最關(guān)鍵的一步就是 SplitWAL,即 HMaster 需要遍歷該 RegionServer 服務(wù)器的 WAL,并按 Region 切分成小塊移動到新的地址下,并進(jìn)行日志的回放(replay)。
由于單個 RegionServer 的日志量相對龐大(可能有上千個 Region,上GB的日志),而用戶又往往希望系統(tǒng)能夠快速完成日志的恢復(fù)工作。因此一個可行的方案是將這個處理WAL的任務(wù)分給多臺 RegionServer 服務(wù)器來共同處理,而這就又需要一個持久化組件來輔助 HMaster 完成任務(wù)的分配。
當(dāng)前的做法是, HMaster 會在 ZooKeeper 上創(chuàng)建一個 SplitWAL 節(jié)點(默認(rèn)情況下,是/hbase/SplitWAL節(jié)點),將“哪個 RegionServer 處理哪個 Region”這樣的信息以列表的形式存放到該節(jié)點上,然后由各個 RegionServer 服務(wù)器自行到該節(jié)點上去領(lǐng)取任務(wù)并在任務(wù)執(zhí)行成功或失敗后再更新該節(jié)點的信息,以通知 HMaster 繼續(xù)進(jìn)行后面的步驟。 ZooKeeper 在這里擔(dān)負(fù)起了分布式集群中相互通知和信息持久化的角色。
5.6 小結(jié):
以上就是一些 HBase 中依賴 ZooKeeper 完成分布式協(xié)調(diào)功能的典型場景。但事實上,HBase 對 ZooKeeper 的依賴還不止這些,比如 HMaster 還依賴 ZooKeeper 來完成 Table 的 enable/disable 狀態(tài)記錄,以及 HBase 中幾乎所有的元數(shù)據(jù)存儲都是放在 ZooKeeper 上的。
由于 ZooKeeper 出色的分布式協(xié)調(diào)能力及良好的通知機制,HBase在各版本的演進(jìn)過程中越來越多地增加了 ZooKeeper 的應(yīng)用場景,從趨勢上來看兩者的交集越來越多。HBase 中所有對 ZooKeeper 的操作都封裝在了 org.apache.hadoop.hbase.zookeeper 這個包中,感興趣的同學(xué)可以自行研究。
以上所述是小編給大家介紹的Spring Boot 模塊組成,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。