真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

深入淺析ZooKeeper的工作原理-創(chuàng)新互聯(lián)

本文講述了ZooKeeper的原理,小編覺(jué)得挺不錯(cuò),分享給大家供大家參考,具體如下:

創(chuàng)新互聯(lián)是一家專(zhuān)業(yè)提供湖北企業(yè)網(wǎng)站建設(shè),專(zhuān)注與成都網(wǎng)站建設(shè)、網(wǎng)站制作成都h5網(wǎng)站建設(shè)、小程序制作等業(yè)務(wù)。10年已為湖北眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專(zhuān)業(yè)網(wǎng)站建設(shè)公司優(yōu)惠進(jìn)行中。

前言


ZooKeeper 是一個(gè)開(kāi)源的分布式協(xié)調(diào)服務(wù),由雅虎創(chuàng)建,是 Google Chubby 的開(kāi)源實(shí)現(xiàn)。分布式應(yīng)用程序可以基于 ZooKeeper 實(shí)現(xiàn)諸如數(shù)據(jù)發(fā)布/訂閱、負(fù)載均衡、命名服務(wù)、分布式協(xié)調(diào)/通知、集群管理、Master 選舉、分布式鎖和分布式隊(duì)列等功能。


1、簡(jiǎn)介

ZooKeeper 是一個(gè)開(kāi)源的分布式協(xié)調(diào)服務(wù),由雅虎創(chuàng)建,是 Google Chubby 的開(kāi)源實(shí)現(xiàn)。分布式應(yīng)用程序可以基于 ZooKeeper 實(shí)現(xiàn)諸如數(shù)據(jù)發(fā)布/訂閱、負(fù)載均衡、命名服務(wù)、分布式協(xié)調(diào)/通知、集群管理、Master 選舉、分布式鎖和分布式隊(duì)列等功能。

2、基本概念

本節(jié)將介紹 ZooKeeper 的幾個(gè)核心概念。這些概念貫穿于之后對(duì) ZooKeeper 更深入的講解,因此有必要預(yù)先了解這些概念。

2.1 集群角色


在 ZooKeeper 中,有三種角色:

Leader

Follower

Observer

一個(gè) ZooKeeper 集群同一時(shí)刻只會(huì)有一個(gè) Leader,其他都是 Follower 或 Observer。


ZooKeeper 配置很簡(jiǎn)單,每個(gè)節(jié)點(diǎn)的配置文件(zoo.cfg)都是一樣的,只有 myid 文件不一樣。myid 的值必須是 zoo.cfg中server.{數(shù)值} 的{數(shù)值}部分。


zoo.cfg 文件內(nèi)容示例:

ZooKeeper


在裝有 ZooKeeper 的機(jī)器的終端執(zhí)行 zookeeper-server status 可以看當(dāng)前節(jié)點(diǎn)的 ZooKeeper 是什么角色(Leader or Follower)。

ZooKeeper


如上,node-20-104 是 Leader,node-20-103 是 follower。


ZooKeeper 默認(rèn)只有 Leader 和 Follower 兩種角色,沒(méi)有 Observer 角色。為了使用 Observer 模式,在任何想變成Observer的節(jié)點(diǎn)的配置文件中加入:peerType=observer 并在所有 server 的配置文件中,配置成 observer 模式的 server 的那行配置追加 :observer,例如:


server.1:localhost:2888:3888:observer


ZooKeeper 集群的所有機(jī)器通過(guò)一個(gè) Leader 選舉過(guò)程來(lái)選定一臺(tái)被稱(chēng)為『Leader』的機(jī)器,Leader服務(wù)器為客戶(hù)端提供讀和寫(xiě)服務(wù)。


Follower 和 Observer 都能提供讀服務(wù),不能提供寫(xiě)服務(wù)。兩者唯一的區(qū)別在于,Observer 機(jī)器不參與 Leader 選舉過(guò)程,也不參與寫(xiě)操作的『過(guò)半寫(xiě)成功』策略,因此 Observer 可以在不影響寫(xiě)性能的情況下提升集群的讀性能。

2.2 會(huì)話(huà)(Session)


Session 是指客戶(hù)端會(huì)話(huà),在講解客戶(hù)端會(huì)話(huà)之前,我們先來(lái)了解下客戶(hù)端連接。在 ZooKeeper 中,一個(gè)客戶(hù)端連接是指客戶(hù)端和 ZooKeeper 服務(wù)器之間的TCP長(zhǎng)連接。


ZooKeeper 對(duì)外的服務(wù)端口默認(rèn)是2181,客戶(hù)端啟動(dòng)時(shí),首先會(huì)與服務(wù)器建立一個(gè)TCP連接,從第一次連接建立開(kāi)始,客戶(hù)端會(huì)話(huà)的生命周期也開(kāi)始了,通過(guò)這個(gè)連接,客戶(hù)端能夠通過(guò)心跳檢測(cè)和服務(wù)器保持有效的會(huì)話(huà),也能夠向 ZooKeeper 服務(wù)器發(fā)送請(qǐng)求并接受響應(yīng),同時(shí)還能通過(guò)該連接接收來(lái)自服務(wù)器的 Watch 事件通知。


Session 的 SessionTimeout 值用來(lái)設(shè)置一個(gè)客戶(hù)端會(huì)話(huà)的超時(shí)時(shí)間。當(dāng)由于服務(wù)器壓力太大、網(wǎng)絡(luò)故障或是客戶(hù)端主動(dòng)斷開(kāi)連接等各種原因?qū)е驴蛻?hù)端連接斷開(kāi)時(shí),只要在 SessionTimeout 規(guī)定的時(shí)間內(nèi)能夠重新連接上集群中任意一臺(tái)服務(wù)器,那么之前創(chuàng)建的會(huì)話(huà)仍然有效。

2.3 數(shù)據(jù)節(jié)點(diǎn)(ZNode)

在談到分布式的時(shí)候,一般『節(jié)點(diǎn)』指的是組成集群的每一臺(tái)機(jī)器。而ZooKeeper 中的數(shù)據(jù)節(jié)點(diǎn)是指數(shù)據(jù)模型中的數(shù)據(jù)單元,稱(chēng)為 ZNode。ZooKeeper 將所有數(shù)據(jù)存儲(chǔ)在內(nèi)存中,數(shù)據(jù)模型是一棵樹(shù)(ZNode Tree),由斜杠(/)進(jìn)行分割的路徑,就是一個(gè)ZNode,如 /hbase/master,其中 hbase 和 master 都是 ZNode。每個(gè) ZNode 上都會(huì)保存自己的數(shù)據(jù)內(nèi)容,同時(shí)會(huì)保存一系列屬性信息。


注:

這里的 ZNode 可以理解成既是Unix里的文件,又是Unix里的目錄。因?yàn)槊總€(gè) ZNode 不僅本身可以寫(xiě)數(shù)據(jù)(相當(dāng)于Unix里的文件),還可以有下一級(jí)文件或目錄(相當(dāng)于Unix里的目錄)。

在 ZooKeeper 中,ZNode 可以分為持久節(jié)點(diǎn)和臨時(shí)節(jié)點(diǎn)兩類(lèi)。


持久節(jié)點(diǎn)


所謂持久節(jié)點(diǎn)是指一旦這個(gè) ZNode 被創(chuàng)建了,除非主動(dòng)進(jìn)行 ZNode 的移除操作,否則這個(gè) ZNode 將一直保存在ZooKeeper 上。


臨時(shí)節(jié)點(diǎn)


臨時(shí)節(jié)點(diǎn)的生命周期跟客戶(hù)端會(huì)話(huà)綁定,一旦客戶(hù)端會(huì)話(huà)失效,那么這個(gè)客戶(hù)端創(chuàng)建的所有臨時(shí)節(jié)點(diǎn)都會(huì)被移除。


另外,ZooKeeper 還允許用戶(hù)為每個(gè)節(jié)點(diǎn)添加一個(gè)特殊的屬性:SEQUENTIAL。一旦節(jié)點(diǎn)被標(biāo)記上這個(gè)屬性,那么在這個(gè)節(jié)點(diǎn)被創(chuàng)建的時(shí)候,ZooKeeper 就會(huì)自動(dòng)在其節(jié)點(diǎn)后面追加上一個(gè)整型數(shù)字,這個(gè)整型數(shù)字是一個(gè)由父節(jié)點(diǎn)維護(hù)的自增數(shù)字。

2.4 版本


ZooKeeper 的每個(gè) ZNode 上都會(huì)存儲(chǔ)數(shù)據(jù),對(duì)應(yīng)于每個(gè) ZNode,ZooKeeper 都會(huì)為其維護(hù)一個(gè)叫作 Stat 的數(shù)據(jù)結(jié)構(gòu),Stat 中記錄了這個(gè) ZNode 的三個(gè)數(shù)據(jù)版本,分別是 version(當(dāng)前ZNode的版本)、cversion(當(dāng)前ZNode子節(jié)點(diǎn)的版本)和 aversion(當(dāng)前 ZNode 的 ACL 版本)。

2.5 狀態(tài)信息


每個(gè) ZNode 除了存儲(chǔ)數(shù)據(jù)內(nèi)容之外,還存儲(chǔ)了 ZNode 本身的一些狀態(tài)信息。用 get 命令可以同時(shí)獲得某個(gè) ZNode 的內(nèi)容和狀態(tài)信息。如下:

ZooKeeper


在 ZooKeeper 中,version 屬性是用來(lái)實(shí)現(xiàn)樂(lè)觀鎖機(jī)制中的『寫(xiě)入校驗(yàn)』的(保證分布式數(shù)據(jù)原子性操作)。

2.6 事務(wù)操作


在ZooKeeper中,能改變ZooKeeper服務(wù)器狀態(tài)的操作稱(chēng)為事務(wù)操作。一般包括數(shù)據(jù)節(jié)點(diǎn)創(chuàng)建與刪除、數(shù)據(jù)內(nèi)容更新和客戶(hù)端會(huì)話(huà)創(chuàng)建與失效等操作。對(duì)應(yīng)每一個(gè)事務(wù)請(qǐng)求,ZooKeeper 都會(huì)為其分配一個(gè)全局唯一的事務(wù)ID,用 ZXID 表示,通常是一個(gè)64位的數(shù)字。每一個(gè) ZXID 對(duì)應(yīng)一次更新操作,從這些 ZXID 中可以間接地識(shí)別出 ZooKeeper 處理這些事務(wù)操作請(qǐng)求的全局順序。

2.7 Watcher


Watcher(事件監(jiān)聽(tīng)器),是 ZooKeeper 中一個(gè)很重要的特性。ZooKeeper允許用戶(hù)在指定節(jié)點(diǎn)上注冊(cè)一些 Watcher,并且在一些特定事件觸發(fā)的時(shí)候,ZooKeeper 服務(wù)端會(huì)將事件通知到感興趣的客戶(hù)端上去。該機(jī)制是 ZooKeeper 實(shí)現(xiàn)分布式協(xié)調(diào)服務(wù)的重要特性。

2.8 ACL


ZooKeeper 采用 ACL(Access Control Lists)策略來(lái)進(jìn)行權(quán)限控制。ZooKeeper 定義了如下5種權(quán)限。


CREATE: 創(chuàng)建子節(jié)點(diǎn)的權(quán)限。


READ: 獲取節(jié)點(diǎn)數(shù)據(jù)和子節(jié)點(diǎn)列表的權(quán)限。


WRITE:更新節(jié)點(diǎn)數(shù)據(jù)的權(quán)限。


DELETE: 刪除子節(jié)點(diǎn)的權(quán)限。


ADMIN: 設(shè)置節(jié)點(diǎn)ACL的權(quán)限。


注意:CREATE 和 DELETE 都是針對(duì)子節(jié)點(diǎn)的權(quán)限控制。

3. ZooKeeper典型應(yīng)用場(chǎng)景


ZooKeeper 是一個(gè)高可用的分布式數(shù)據(jù)管理與協(xié)調(diào)框架?;趯?duì)ZAB算法的實(shí)現(xiàn),該框架能夠很好地保證分布式環(huán)境中數(shù)據(jù)的一致性。也是基于這樣的特性,使得 ZooKeeper 成為了解決分布式一致性問(wèn)題的利器。

3.1 數(shù)據(jù)發(fā)布與訂閱(配置中心)


數(shù)據(jù)發(fā)布與訂閱,即所謂的配置中心,顧名思義就是發(fā)布者將數(shù)據(jù)發(fā)布到 ZooKeeper 節(jié)點(diǎn)上,供訂閱者進(jìn)行數(shù)據(jù)訂閱,進(jìn)而達(dá)到動(dòng)態(tài)獲取數(shù)據(jù)的目的,實(shí)現(xiàn)配置信息的集中式管理和動(dòng)態(tài)更新。


在我們平常的應(yīng)用系統(tǒng)開(kāi)發(fā)中,經(jīng)常會(huì)碰到這樣的需求:系統(tǒng)中需要使用一些通用的配置信息,例如機(jī)器列表信息、數(shù)據(jù)庫(kù)配置信息等。這些全局配置信息通常具備以下3個(gè)特性。

數(shù)據(jù)量通常比較小。


數(shù)據(jù)內(nèi)容在運(yùn)行時(shí)動(dòng)態(tài)變化。


集群中各機(jī)器共享,配置一致。


對(duì)于這樣的全局配置信息就可以發(fā)布到 ZooKeeper上,讓客戶(hù)端(集群的機(jī)器)去訂閱該消息。


發(fā)布/訂閱系統(tǒng)一般有兩種設(shè)計(jì)模式,分別是推(Push)和拉(Pull)模式。


推:服務(wù)端主動(dòng)將數(shù)據(jù)更新發(fā)送給所有訂閱的客戶(hù)端。


拉:客戶(hù)端主動(dòng)發(fā)起請(qǐng)求來(lái)獲取最新數(shù)據(jù),通??蛻?hù)端都采用定時(shí)輪詢(xún)拉取的方式。


ZooKeeper 采用的是推拉相結(jié)合的方式。如下:


客戶(hù)端想服務(wù)端注冊(cè)自己需要關(guān)注的節(jié)點(diǎn),一旦該節(jié)點(diǎn)的數(shù)據(jù)發(fā)生變更,那么服務(wù)端就會(huì)向相應(yīng)的客戶(hù)端發(fā)送Watcher事件通知,客戶(hù)端接收到這個(gè)消息通知后,需要主動(dòng)到服務(wù)端獲取最新的數(shù)據(jù)(推拉結(jié)合)。

3.2 命名服務(wù)(Naming Service)


命名服務(wù)也是分布式系統(tǒng)中比較常見(jiàn)的一類(lèi)場(chǎng)景。在分布式系統(tǒng)中,通過(guò)使用命名服務(wù),客戶(hù)端應(yīng)用能夠根據(jù)指定名字來(lái)獲取資源或服務(wù)的地址,提供者等信息。被命名的實(shí)體通??梢允羌褐械臋C(jī)器,提供的服務(wù),遠(yuǎn)程對(duì)象等等——這些我們都可以統(tǒng)稱(chēng)他們?yōu)槊郑∟ame)。


其中較為常見(jiàn)的就是一些分布式服務(wù)框架(如RPC、RMI)中的服務(wù)地址列表。通過(guò)在ZooKeepr里創(chuàng)建順序節(jié)點(diǎn),能夠很容易創(chuàng)建一個(gè)全局唯一的路徑,這個(gè)路徑就可以作為一個(gè)名字。


ZooKeeper 的命名服務(wù)即生成全局唯一的ID。

3.3 分布式協(xié)調(diào)/通知


ZooKeeper 中特有 Watcher 注冊(cè)與異步通知機(jī)制,能夠很好的實(shí)現(xiàn)分布式環(huán)境下不同機(jī)器,甚至不同系統(tǒng)之間的通知與協(xié)調(diào),從而實(shí)現(xiàn)對(duì)數(shù)據(jù)變更的實(shí)時(shí)處理。使用方法通常是不同的客戶(hù)端都對(duì)ZK上同一個(gè) ZNode 進(jìn)行注冊(cè),監(jiān)聽(tīng) ZNode 的變化(包括ZNode本身內(nèi)容及子節(jié)點(diǎn)的),如果 ZNode 發(fā)生了變化,那么所有訂閱的客戶(hù)端都能夠接收到相應(yīng)的Watcher通知,并做出相應(yīng)的處理。


ZK的分布式協(xié)調(diào)/通知,是一種通用的分布式系統(tǒng)機(jī)器間的通信方式。

3.3.1 心跳檢測(cè)

機(jī)器間的心跳檢測(cè)機(jī)制是指在分布式環(huán)境中,不同機(jī)器(或進(jìn)程)之間需要檢測(cè)到彼此是否在正常運(yùn)行,例如A機(jī)器需要知道B機(jī)器是否正常運(yùn)行。在傳統(tǒng)的開(kāi)發(fā)中,我們通常是通過(guò)主機(jī)直接是否可以相互PING通來(lái)判斷,更復(fù)雜一點(diǎn)的話(huà),則會(huì)通過(guò)在機(jī)器之間建立長(zhǎng)連接,通過(guò)TCP連接固有的心跳檢測(cè)機(jī)制來(lái)實(shí)現(xiàn)上層機(jī)器的心跳檢測(cè),這些都是非常常見(jiàn)的心跳檢測(cè)方法。


下面來(lái)看看如何使用ZK來(lái)實(shí)現(xiàn)分布式機(jī)器(進(jìn)程)間的心跳檢測(cè)。


基于ZK的臨時(shí)節(jié)點(diǎn)的特性,可以讓不同的進(jìn)程都在ZK的一個(gè)指定節(jié)點(diǎn)下創(chuàng)建臨時(shí)子節(jié)點(diǎn),不同的進(jìn)程直接可以根據(jù)這個(gè)臨時(shí)子節(jié)點(diǎn)來(lái)判斷對(duì)應(yīng)的進(jìn)程是否存活。通過(guò)這種方式,檢測(cè)和被檢測(cè)系統(tǒng)直接并不需要直接相關(guān)聯(lián),而是通過(guò)ZK上的某個(gè)節(jié)點(diǎn)進(jìn)行關(guān)聯(lián),大大減少了系統(tǒng)耦合。

3.3.2 工作進(jìn)度匯報(bào)

在一個(gè)常見(jiàn)的任務(wù)分發(fā)系統(tǒng)中,通常任務(wù)被分發(fā)到不同的機(jī)器上執(zhí)行后,需要實(shí)時(shí)地將自己的任務(wù)執(zhí)行進(jìn)度匯報(bào)給分發(fā)系統(tǒng)。這個(gè)時(shí)候就可以通過(guò)ZK來(lái)實(shí)現(xiàn)。在ZK上選擇一個(gè)節(jié)點(diǎn),每個(gè)任務(wù)客戶(hù)端都在這個(gè)節(jié)點(diǎn)下面創(chuàng)建臨時(shí)子節(jié)點(diǎn),這樣便可以實(shí)現(xiàn)兩個(gè)功能:


通過(guò)判斷臨時(shí)節(jié)點(diǎn)是否存在來(lái)確定任務(wù)機(jī)器是否存活。

各個(gè)任務(wù)機(jī)器會(huì)實(shí)時(shí)地將自己的任務(wù)執(zhí)行進(jìn)度寫(xiě)到這個(gè)臨時(shí)節(jié)點(diǎn)上去,以便中心系統(tǒng)能夠?qū)崟r(shí)地獲取到任務(wù)的執(zhí)行進(jìn)度。

3.4 Master選舉


Master 選舉可以說(shuō)是 ZooKeeper 最典型的應(yīng)用場(chǎng)景了。比如 HDFS 中 Active NameNode 的選舉、YARN 中 Active ResourceManager 的選舉和 HBase 中 Active HMaster 的選舉等。


針對(duì) Master 選舉的需求,通常情況下,我們可以選擇常見(jiàn)的關(guān)系型數(shù)據(jù)庫(kù)中的主鍵特性來(lái)實(shí)現(xiàn):希望成為 Master 的機(jī)器都向數(shù)據(jù)庫(kù)中插入一條相同主鍵ID的記錄,數(shù)據(jù)庫(kù)會(huì)幫我們進(jìn)行主鍵沖突檢查,也就是說(shuō),只有一臺(tái)機(jī)器能插入成功——那么,我們就認(rèn)為向數(shù)據(jù)庫(kù)中成功插入數(shù)據(jù)的客戶(hù)端機(jī)器成為Master。


依靠關(guān)系型數(shù)據(jù)庫(kù)的主鍵特性確實(shí)能夠很好地保證在集群中選舉出唯一的一個(gè)Master。


但是,如果當(dāng)前選舉出的 Master 掛了,那么該如何處理?誰(shuí)來(lái)告訴我 Master 掛了呢?顯然,關(guān)系型數(shù)據(jù)庫(kù)無(wú)法通知我們這個(gè)事件。但是,ZooKeeper 可以做到!


利用 ZooKeepr 的強(qiáng)一致性,能夠很好地保證在分布式高并發(fā)情況下節(jié)點(diǎn)的創(chuàng)建一定能夠保證全局唯一性,即 ZooKeeper 將會(huì)保證客戶(hù)端無(wú)法創(chuàng)建一個(gè)已經(jīng)存在的 ZNode。


也就是說(shuō),如果同時(shí)有多個(gè)客戶(hù)端請(qǐng)求創(chuàng)建同一個(gè)臨時(shí)節(jié)點(diǎn),那么最終一定只有一個(gè)客戶(hù)端請(qǐng)求能夠創(chuàng)建成功。利用這個(gè)特性,就能很容易地在分布式環(huán)境中進(jìn)行 Master 選舉了。


成功創(chuàng)建該節(jié)點(diǎn)的客戶(hù)端所在的機(jī)器就成為了 Master。同時(shí),其他沒(méi)有成功創(chuàng)建該節(jié)點(diǎn)的客戶(hù)端,都會(huì)在該節(jié)點(diǎn)上注冊(cè)一個(gè)子節(jié)點(diǎn)變更的 Watcher,用于監(jiān)控當(dāng)前 Master 機(jī)器是否存活,一旦發(fā)現(xiàn)當(dāng)前的Master掛了,那么其他客戶(hù)端將會(huì)重新進(jìn)行 Master 選舉。


這樣就實(shí)現(xiàn)了 Master 的動(dòng)態(tài)選舉。

3.5 分布式鎖


分布式鎖是控制分布式系統(tǒng)之間同步訪(fǎng)問(wèn)共享資源的一種方式。


分布式鎖又分為排他鎖和共享鎖兩種。

3.5.1 排他鎖

排他鎖(Exclusive Locks,簡(jiǎn)稱(chēng)X鎖),又稱(chēng)為寫(xiě)鎖或獨(dú)占鎖。


如果事務(wù)T1對(duì)數(shù)據(jù)對(duì)象O1加上了排他鎖,那么在整個(gè)加鎖期間,只允許事務(wù)T1對(duì)O1進(jìn)行讀取和更新操作,其他任何事務(wù)都不能在對(duì)這個(gè)數(shù)據(jù)對(duì)象進(jìn)行任何類(lèi)型的操作(不能再對(duì)該對(duì)象加鎖),直到T1釋放了排他鎖。

可以看出,排他鎖的核心是如何保證當(dāng)前只有一個(gè)事務(wù)獲得鎖,并且鎖被釋放后,所有正在等待獲取鎖的事務(wù)都能夠被通知到。


如何利用 ZooKeeper 實(shí)現(xiàn)排他鎖?


定義鎖


ZooKeeper 上的一個(gè) ZNode 可以表示一個(gè)鎖。例如 /exclusive_lock/lock節(jié)點(diǎn)就可以被定義為一個(gè)鎖。


獲得鎖


如上所說(shuō),把ZooKeeper上的一個(gè)ZNode看作是一個(gè)鎖,獲得鎖就通過(guò)創(chuàng)建 ZNode 的方式來(lái)實(shí)現(xiàn)。所有客戶(hù)端都去 /exclusive_lock節(jié)點(diǎn)下創(chuàng)建臨時(shí)子節(jié)點(diǎn) /exclusive_lock/lock。ZooKeeper 會(huì)保證在所有客戶(hù)端中,最終只有一個(gè)客戶(hù)端能夠創(chuàng)建成功,那么就可以認(rèn)為該客戶(hù)端獲得了鎖。同時(shí),所有沒(méi)有獲取到鎖的客戶(hù)端就需要到/exclusive_lock節(jié)點(diǎn)上注冊(cè)一個(gè)子節(jié)點(diǎn)變更的Watcher監(jiān)聽(tīng),以便實(shí)時(shí)監(jiān)聽(tīng)到lock節(jié)點(diǎn)的變更情況。


釋放鎖


因?yàn)?/exclusive_lock/lock 是一個(gè)臨時(shí)節(jié)點(diǎn),因此在以下兩種情況下,都有可能釋放鎖。


當(dāng)前獲得鎖的客戶(hù)端機(jī)器發(fā)生宕機(jī)或重啟,那么該臨時(shí)節(jié)點(diǎn)就會(huì)被刪除,釋放鎖。


正常執(zhí)行完業(yè)務(wù)邏輯后,客戶(hù)端就會(huì)主動(dòng)將自己創(chuàng)建的臨時(shí)節(jié)點(diǎn)刪除,釋放鎖。


無(wú)論在什么情況下移除了lock節(jié)點(diǎn),ZooKeeper 都會(huì)通知所有在 /exclusive_lock 節(jié)點(diǎn)上注冊(cè)了節(jié)點(diǎn)變更 Watcher 監(jiān)聽(tīng)的客戶(hù)端。這些客戶(hù)端在接收到通知后,再次重新發(fā)起分布式鎖獲取,即重復(fù)『獲取鎖』過(guò)程。

3.5.2 共享鎖


共享鎖(Shared Locks,簡(jiǎn)稱(chēng)S鎖),又稱(chēng)為讀鎖。如果事務(wù)T1對(duì)數(shù)據(jù)對(duì)象O1加上了共享鎖,那么T1只能對(duì)O1進(jìn)行讀操作,其他事務(wù)也能同時(shí)對(duì)O1加共享鎖(不能是排他鎖),直到O1上的所有共享鎖都釋放后O1才能被加排他鎖。


總結(jié):可以多個(gè)事務(wù)同時(shí)獲得一個(gè)對(duì)象的共享鎖(同時(shí)讀),有共享鎖就不能再加排他鎖(因?yàn)榕潘i是寫(xiě)鎖)

4、ZooKeeper在大型分布式系統(tǒng)中的應(yīng)用


前面已經(jīng)介紹了 ZooKeeper 的典型應(yīng)用場(chǎng)景。本節(jié)將以常見(jiàn)的大數(shù)據(jù)產(chǎn)品 Hadoop 和 HBase 為例來(lái)介紹 ZooKeeper 在其中的應(yīng)用,幫助大家更好地理解 ZooKeeper 的分布式應(yīng)用場(chǎng)景。

4.1 ZooKeeper在Hadoop中的應(yīng)用


在 Hadoop 中,ZooKeeper 主要用于實(shí)現(xiàn) HA(Hive Availability),包括 HDFS的 NamaNode 和 YARN 的 ResourceManager 的 HA。同時(shí),在 YARN 中, ZooKeepr 還用來(lái)存儲(chǔ)應(yīng)用的運(yùn)行狀態(tài)。
HDFS 的 NamaNode 和 YARN 的 ResourceManager 利用 ZooKeepr 實(shí)現(xiàn) HA 的原理是一樣的,所以本節(jié)以YARN為例來(lái)介紹。

ZooKeeper


從上圖可以看出,YARN主要由ResourceManager(RM)、NodeManager(NM)、ApplicationMaster(AM)和Container四部分組成。其中最核心的就是ResourceManager。


ResourceManager 負(fù)責(zé)集群中所有資源的統(tǒng)一管理和分配,同時(shí)接收來(lái)自各個(gè)節(jié)點(diǎn)(NodeManager)的資源匯報(bào)信息,并把這些信息按照一定的策略分配給各個(gè)應(yīng)用程序(Application Manager),其內(nèi)部維護(hù)了各個(gè)應(yīng)用程序的ApplicationMaster信息、NodeManager信息以及資源使用信息等。


為了實(shí)現(xiàn)HA,必須有多個(gè)ResourceManager并存(一般就兩個(gè)),并且只有一個(gè)ResourceManager處于Active狀態(tài),其他的則處于Standby狀態(tài),當(dāng)Active節(jié)點(diǎn)無(wú)法正常工作(如機(jī)器宕機(jī)或重啟)時(shí),處于Standby的就會(huì)通過(guò)競(jìng)爭(zhēng)選舉產(chǎn)生新的Active節(jié)點(diǎn)。

4.2 主備切換


下面我們就來(lái)看看YARN是如何實(shí)現(xiàn)多個(gè)ResourceManager之間的主備切換的。


1. 創(chuàng)建鎖節(jié)點(diǎn)
在 ZooKeeper 上會(huì)有一個(gè)/yarn-leader-election/appcluster-yarn的鎖節(jié)點(diǎn),所有的 ResourceManager 在啟動(dòng)的時(shí)候,都會(huì)去競(jìng)爭(zhēng)寫(xiě)一個(gè)Lock子節(jié)點(diǎn):/yarn-leader-election/appcluster-yarn/ActiveBreadCrumb,該節(jié)點(diǎn)是臨時(shí)節(jié)點(diǎn)。


ZooKeepr 能夠?yàn)槲覀儽WC最終只有一個(gè)ResourceManager能夠創(chuàng)建成功。創(chuàng)建成功的那個(gè) ResourceManager 就切換為 Active 狀態(tài),沒(méi)有成功的那些 ResourceManager 則切換為 Standby 狀態(tài)。


ZooKeeper


可以看到此時(shí)集群中 ResourceManager2 為 Active。


注冊(cè) Watcher 監(jiān)聽(tīng)


所有 Standby 狀態(tài)的 ResourceManager 都會(huì)向 /yarn-leader-election/appcluster-yarn/ActiveBreadCrumb 節(jié)點(diǎn)注冊(cè)一個(gè)節(jié)點(diǎn)變更的Watcher監(jiān)聽(tīng),利用臨時(shí)節(jié)點(diǎn)的特性,能夠快速感知到Active狀態(tài)的ResourceManager的運(yùn)行情況。


主備切換


當(dāng)Active狀態(tài)的ResourceManager出現(xiàn)諸如宕機(jī)或重啟的異常情況時(shí),其在ZooKeeper上連接的客戶(hù)端會(huì)話(huà)就會(huì)失效,因此/yarn-leader-election/appcluster-yarn/ActiveBreadCrumb節(jié)點(diǎn)就會(huì)被刪除。此時(shí)其余各個(gè)Standby狀態(tài)的ResourceManager就都會(huì)接收到來(lái)自ZooKeeper服務(wù)端的Watcher事件通知,然后會(huì)重復(fù)進(jìn)行步驟1的操作。


以上就是利用 ZooKeeper 來(lái)實(shí)現(xiàn) ResourceManager 的主備切換的過(guò)程,實(shí)現(xiàn)了 ResourceManager 的HA。


HDFS 中 NameNode 的 HA 的實(shí)現(xiàn)原理跟 YARN 中 ResourceManager 的 HA 的實(shí)現(xiàn)原理相同。其鎖節(jié)點(diǎn)為 /hadoop-ha/mycluster/ActiveBreadCrumb。

4.3 ResourceManager狀態(tài)存儲(chǔ)


在 ResourceManager 中,RMStateStore 能夠存儲(chǔ)一些 RM 的內(nèi)部狀態(tài)信息,包括 Application 以及它們的 Attempts 信息、Delegation Token 及 Version Information 等。需要注意的是,RMStateStore 中的絕大多數(shù)狀態(tài)信息都是不需要持久化存儲(chǔ)的,因?yàn)楹苋菀讖纳舷挛男畔⒅袑⑵渲貥?gòu)出來(lái),如資源的使用情況。在存儲(chǔ)的設(shè)計(jì)方案中,提供了三種可能的實(shí)現(xiàn),分別如下。


基于內(nèi)存實(shí)現(xiàn),一般是用于日常開(kāi)發(fā)測(cè)試。


基于文件系統(tǒng)的實(shí)現(xiàn),如HDFS。


基于 ZooKeeper 實(shí)現(xiàn)。


由于這些狀態(tài)信息的數(shù)據(jù)量都不是很大,因此 Hadoop 官方建議基于 ZooKeeper 來(lái)實(shí)現(xiàn)狀態(tài)信息的存儲(chǔ)。在 ZooKeepr 上,ResourceManager 的狀態(tài)信息都被存儲(chǔ)在 /rmstore 這個(gè)根節(jié)點(diǎn)下面。

ZooKeeper


RMAppRoot 節(jié)點(diǎn)下存儲(chǔ)的是與各個(gè) Application 相關(guān)的信息,RMDTSecretManagerRoot 存儲(chǔ)的是與安全相關(guān)的 Token 等信息。每個(gè) Active 狀態(tài)的 ResourceManager 在初始化階段都會(huì)從 ZooKeeper 上讀取到這些狀態(tài)信息,并根據(jù)這些狀態(tài)信息繼續(xù)進(jìn)行相應(yīng)的處理。

4.4 小結(jié):


ZooKeepr 在 Hadoop 中的應(yīng)用主要有:

HDFS 中 NameNode 的 HA 和 YARN 中 ResourceManager 的 HA。

存儲(chǔ) RMStateStore 狀態(tài)信息

5、ZooKeeper在HBase中的應(yīng)用

HBase 主要用 ZooKeeper 來(lái)實(shí)現(xiàn) HMaster 選舉與主備切換、系統(tǒng)容錯(cuò)、RootRegion 管理、Region狀態(tài)管理和分布式

SplitWAL 任務(wù)管理等。

5.1 HMaster選舉與主備切換


HMaster選舉與主備切換的原理和HDFS中NameNode及YARN中ResourceManager的HA原理相同。

5.2 系統(tǒng)容錯(cuò)

當(dāng) HBase 啟動(dòng)時(shí),每個(gè) RegionServer 都會(huì)到 ZooKeeper 的/hbase/rs節(jié)點(diǎn)下創(chuàng)建一個(gè)信息節(jié)點(diǎn)(下文中,我們稱(chēng)該節(jié)點(diǎn)為”rs狀態(tài)節(jié)點(diǎn)”),例如/hbase/rs/[Hostname],同時(shí),HMaster 會(huì)對(duì)這個(gè)節(jié)點(diǎn)注冊(cè)監(jiān)聽(tīng)。當(dāng)某個(gè) RegionServer 掛掉的時(shí)候,ZooKeeper 會(huì)因?yàn)樵谝欢螘r(shí)間內(nèi)無(wú)法接受其心跳(即 Session 失效),而刪除掉該 RegionServer 服務(wù)器對(duì)應(yīng)的 rs 狀態(tài)節(jié)點(diǎn)。


與此同時(shí),HMaster 則會(huì)接收到 ZooKeeper 的 NodeDelete 通知,從而感知到某個(gè)節(jié)點(diǎn)斷開(kāi),并立即開(kāi)始容錯(cuò)工作。


HBase 為什么不直接讓 HMaster 來(lái)負(fù)責(zé) RegionServer 的監(jiān)控呢?如果 HMaster 直接通過(guò)心跳機(jī)制等來(lái)管理RegionServer的狀態(tài),隨著集群越來(lái)越大,HMaster 的管理負(fù)擔(dān)會(huì)越來(lái)越重,另外它自身也有掛掉的可能,因此數(shù)據(jù)還需要持久化。在這種情況下,ZooKeeper 就成了理想的選擇。

5.3 RootRegion管理


對(duì)應(yīng) HBase 集群來(lái)說(shuō),數(shù)據(jù)存儲(chǔ)的位置信息是記錄在元數(shù)據(jù) region,也就是 RootRegion 上的。每次客戶(hù)端發(fā)起新的請(qǐng)求,需要知道數(shù)據(jù)的位置,就會(huì)去查詢(xún) RootRegion,而 RootRegion 自身位置則是記錄在 ZooKeeper 上的(默認(rèn)情況下,是記錄在 ZooKeeper 的/hbase/meta-region-server節(jié)點(diǎn)中)。


當(dāng) RootRegion 發(fā)生變化,比如 Region 的手工移動(dòng)、重新負(fù)載均衡或 RootRegion 所在服務(wù)器發(fā)生了故障等是,就能夠通過(guò) ZooKeeper 來(lái)感知到這一變化并做出一系列相應(yīng)的容災(zāi)措施,從而保證客戶(hù)端總是能夠拿到正確的 RootRegion 信息。

5.4 Region管理


HBase 里的 Region 會(huì)經(jīng)常發(fā)生變更,這些變更的原因來(lái)自于系統(tǒng)故障、負(fù)載均衡、配置修改、Region 分裂與合并等。一旦 Region 發(fā)生移動(dòng),它就會(huì)經(jīng)歷下線(xiàn)(offline)和重新上線(xiàn)(online)的過(guò)程。


在下線(xiàn)期間數(shù)據(jù)是不能被訪(fǎng)問(wèn)的,并且 Region 的這個(gè)狀態(tài)變化必須讓全局知曉,否則可能會(huì)出現(xiàn)事務(wù)性的異常。


對(duì)于大的 HBase 集群來(lái)說(shuō),Region 的數(shù)量可能會(huì)多達(dá)十萬(wàn)級(jí)別,甚至更多,這樣規(guī)模的 Region 狀態(tài)管理交給 ZooKeeper 來(lái)做也是一個(gè)很好的選擇。

5.5 分布式SplitWAL任務(wù)管理


當(dāng)某臺(tái) RegionServer 服務(wù)器掛掉時(shí),由于總有一部分新寫(xiě)入的數(shù)據(jù)還沒(méi)有持久化到 HFile 中,因此在遷移該 RegionServer 的服務(wù)時(shí),一個(gè)重要的工作就是從 WAL 中恢復(fù)這部分還在內(nèi)存中的數(shù)據(jù),而這部分工作最關(guān)鍵的一步就是 SplitWAL,即 HMaster 需要遍歷該 RegionServer 服務(wù)器的 WAL,并按 Region 切分成小塊移動(dòng)到新的地址下,并進(jìn)行日志的回放(replay)。


由于單個(gè) RegionServer 的日志量相對(duì)龐大(可能有上千個(gè) Region,上GB的日志),而用戶(hù)又往往希望系統(tǒng)能夠快速完成日志的恢復(fù)工作。因此一個(gè)可行的方案是將這個(gè)處理WAL的任務(wù)分給多臺(tái) RegionServer 服務(wù)器來(lái)共同處理,而這就又需要一個(gè)持久化組件來(lái)輔助 HMaster 完成任務(wù)的分配。


當(dāng)前的做法是, HMaster 會(huì)在 ZooKeeper 上創(chuàng)建一個(gè) SplitWAL 節(jié)點(diǎn)(默認(rèn)情況下,是/hbase/SplitWAL節(jié)點(diǎn)),將“哪個(gè) RegionServer 處理哪個(gè) Region”這樣的信息以列表的形式存放到該節(jié)點(diǎn)上,然后由各個(gè) RegionServer 服務(wù)器自行到該節(jié)點(diǎn)上去領(lǐng)取任務(wù)并在任務(wù)執(zhí)行成功或失敗后再更新該節(jié)點(diǎn)的信息,以通知 HMaster 繼續(xù)進(jìn)行后面的步驟。 ZooKeeper 在這里擔(dān)負(fù)起了分布式集群中相互通知和信息持久化的角色。

5.6 小結(jié):
以上就是一些 HBase 中依賴(lài) ZooKeeper 完成分布式協(xié)調(diào)功能的典型場(chǎng)景。但事實(shí)上,HBase 對(duì) ZooKeeper 的依賴(lài)還不止這些,比如 HMaster 還依賴(lài) ZooKeeper 來(lái)完成 Table 的 enable/disable 狀態(tài)記錄,以及 HBase 中幾乎所有的元數(shù)據(jù)存儲(chǔ)都是放在 ZooKeeper 上的。


由于 ZooKeeper 出色的分布式協(xié)調(diào)能力及良好的通知機(jī)制,HBase在各版本的演進(jìn)過(guò)程中越來(lái)越多地增加了 ZooKeeper 的應(yīng)用場(chǎng)景,從趨勢(shì)上來(lái)看兩者的交集越來(lái)越多。HBase 中所有對(duì) ZooKeeper 的操作都封裝在了 org.apache.hadoop.hbase.zookeeper 這個(gè)包中,感興趣的同學(xué)可以自行研究。


以上所述是小編給大家介紹的Spring Boot 模塊組成,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的!


文章名稱(chēng):深入淺析ZooKeeper的工作原理-創(chuàng)新互聯(lián)
當(dāng)前鏈接:http://weahome.cn/article/dojsgp.html

其他資訊

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部