三、ZooKeeper的典型應(yīng)用場(chǎng)景

ZooKeeper是一個(gè)典型的發(fā)布/訂閱模式的分布式數(shù)據(jù)管理與協(xié)調(diào)框架,開發(fā)人員可以使用它來(lái)進(jìn)行分布式數(shù)據(jù)的發(fā)布與訂閱。另一方面,通過(guò)對(duì)ZooKeeper中豐富的數(shù)據(jù)節(jié)點(diǎn)類型進(jìn)行交叉使用,配合Watcher事件通知機(jī)制,可以非常方便的構(gòu)建一系列分布式應(yīng)用中都會(huì)涉及的核心功能,如數(shù)據(jù)發(fā)布/訂閱、負(fù)載均衡、命名服務(wù)、分布式協(xié)調(diào)/通知、集群管理、Master選舉、分布式鎖和分布式隊(duì)列等。

一、典型應(yīng)用場(chǎng)景及實(shí)現(xiàn)

1.1 數(shù)據(jù)發(fā)布/訂閱

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

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

  • 推模式

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

  • 拉模式

客戶端通過(guò)采用定時(shí)輪詢拉取。

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

1.2 負(fù)載均衡

根據(jù)維基百科的定義,負(fù)載均衡(Load Balance)是一種相當(dāng)常見(jiàn)的計(jì)算機(jī)網(wǎng)絡(luò)技術(shù),用來(lái)對(duì)多個(gè)計(jì)算機(jī)(計(jì)算機(jī)集群)、網(wǎng)絡(luò)連接、CPU、硬盤驅(qū)動(dòng)器或其他資源進(jìn)行分配負(fù)載,以達(dá)到優(yōu)化資源使用、最大化吞吐率、最小化響應(yīng)時(shí)間和避免過(guò)載的目的。通常,負(fù)載均衡可以分為硬件和軟件負(fù)載均衡兩類。

1.3 命名服務(wù)

命名服務(wù)(Name Service)也是分布式系統(tǒng)中比較常見(jiàn)的一類場(chǎng)景。在《Java網(wǎng)絡(luò)高級(jí)編程》一書中提到,命名服務(wù)是分布式系統(tǒng)最基本的公共服務(wù)之一。在分布式系統(tǒng)中,被命名的實(shí)體通常是集群中的機(jī)器、提供的服務(wù)地址或遠(yuǎn)程對(duì)象等--這些我們都可以統(tǒng)稱他們?yōu)槊?,其中比較常見(jiàn)的就是一些分布式服務(wù)框架(RPC、RMI)中的服務(wù)地址列表,通過(guò)使用命名服務(wù),客戶端應(yīng)用能夠根據(jù)指定名字來(lái)獲取資源的實(shí)體、服務(wù)地址和提供者信息等。

Java語(yǔ)言中的JNDI便是一種典型的命名服務(wù)。JNDI是Java命名和目錄接口(Java Naming and Directory Interface)的縮寫,是J2EE體系中重要的規(guī)范之一,標(biāo)準(zhǔn)的J2EE容器都提供了對(duì)JNDI規(guī)范的實(shí)現(xiàn)。因此,在實(shí)際開發(fā)中,開發(fā)人員常常使用應(yīng)用服務(wù)器自帶的JNDI實(shí)現(xiàn)來(lái)完成數(shù)據(jù)源的配置與管理--使用JNDI方式后,開發(fā)人員可以完全不需要關(guān)心與數(shù)據(jù)庫(kù)相關(guān)的任何信息,包括數(shù)據(jù)庫(kù)類型、JDBC驅(qū)動(dòng)類型以及數(shù)據(jù)庫(kù)賬戶等。

ZooKeeper提供的命名服務(wù)功能與JNDI技術(shù)有類似的地方,都能夠幫助應(yīng)用系統(tǒng)通過(guò)一個(gè)資源引用的方式來(lái)實(shí)現(xiàn)對(duì)資源的定位與使用。另外,廣義上命名服務(wù)的資源定位都不是真正意義的實(shí)體資源--在分布式環(huán)境中,上層應(yīng)用僅僅需要一個(gè)全局唯一的名字,類似于數(shù)據(jù)庫(kù)的唯一主鍵。下面我們看看如何使用ZooKeeper來(lái)實(shí)現(xiàn)一套分布式全局唯一ID的分配機(jī)制。

所謂ID,就是一個(gè)能唯一標(biāo)識(shí)某個(gè)對(duì)象的標(biāo)識(shí)符。一說(shuō)起全局唯一ID,相信讀者都會(huì)聯(lián)想到UUID。UUID是通用唯一標(biāo)識(shí)碼(Universally Unique Identifier)的簡(jiǎn)稱,是一種在分布式系統(tǒng)中廣泛使用的用于唯一標(biāo)識(shí)元素的標(biāo)準(zhǔn),最典型的實(shí)現(xiàn)是GUID(Globally Unique Identifier,全局唯一標(biāo)識(shí)符),主流ORM框架Hibernate有對(duì)UUID的直接支持。

一個(gè)標(biāo)準(zhǔn)的UUID是一個(gè)包含32位字符和4各短線的字符串。他的優(yōu)勢(shì)自然不必多說(shuō),我們來(lái)看看他的缺陷。

  • 長(zhǎng)度過(guò)長(zhǎng)

和數(shù)據(jù)庫(kù)中的INT類型相比,存儲(chǔ)一個(gè)UUID需要花費(fèi)更多的空間。

  • 含義不明

根據(jù)字面完全看不出任何含義,這會(huì)大大影響問(wèn)題排查和開發(fā)調(diào)試的效率。

接下來(lái)我們來(lái)講解使用ZooKeeper生成唯一ID的基本步驟。

  • 所有客戶端都會(huì)根據(jù)自己的任務(wù)類型,在指定類型的任務(wù)下面通過(guò)調(diào)用create()接口來(lái)創(chuàng)建一個(gè)順序節(jié)點(diǎn),例如創(chuàng)建“job-”節(jié)點(diǎn)。
  • 節(jié)點(diǎn)創(chuàng)建完畢后,create()接口會(huì)返回一個(gè)完整的節(jié)點(diǎn)名,例如“job-0000000003”。
  • 客戶端拿到這個(gè)返回值后,拼接上type類型,例如“type2-job-0000000003”,這樣就可以作為一個(gè)全局唯一的ID了。

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

分布式協(xié)調(diào)/通知是將不同的分布式組件有機(jī)結(jié)合起來(lái)的關(guān)鍵所在。對(duì)于一個(gè)在多臺(tái)機(jī)器上部署運(yùn)行的應(yīng)用而言,通常需要一個(gè)協(xié)調(diào)者(Coordinator)來(lái)控制整個(gè)系統(tǒng)的運(yùn)行流程,例如分布式事務(wù)的處理、機(jī)器間的相互協(xié)調(diào)等。同時(shí),引入這樣一個(gè)協(xié)調(diào)者,便于將分布式協(xié)調(diào)的職責(zé)從應(yīng)用中分離出來(lái),從而大大減少系統(tǒng)之家的耦合性,而且能夠顯著提高系統(tǒng)的可擴(kuò)展性。

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

一種通用的分布式系統(tǒng)機(jī)器間通信方式

心跳檢測(cè)

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

下面看看如何使用ZooKeeper來(lái)實(shí)現(xiàn)分布式機(jī)器間的心跳檢測(cè)?;赯ooKeeper的臨時(shí)節(jié)點(diǎn)特性,可以讓不同的機(jī)器都在ZooKeeper的一個(gè)指定節(jié)點(diǎn)下創(chuàng)建臨時(shí)子節(jié)點(diǎn),不同的機(jī)器之間可以根據(jù)這個(gè)臨時(shí)節(jié)點(diǎn)來(lái)判斷對(duì)應(yīng)的客戶端機(jī)器是否存活。通過(guò)這種方式,檢測(cè)系統(tǒng)和被檢測(cè)系統(tǒng)間并不需要直接相關(guān)聯(lián),而是通過(guò)ZooKeeper上的某個(gè)節(jié)點(diǎn)進(jìn)行關(guān)聯(lián),大大減少了系統(tǒng)耦合。

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

系統(tǒng)調(diào)度

后臺(tái)管理人員操作控制臺(tái),實(shí)際上修改ZooKeeper某些節(jié)點(diǎn)的數(shù)據(jù),然后ZooKeeper把這些數(shù)據(jù)變更以事件通知的形式發(fā)送給了對(duì)應(yīng)的訂閱客戶端。

1.5 集群管理

1.6 Master選舉

1.7 分布式鎖

1.8 分布式隊(duì)列

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

2.1 Hadoop

在Hadoop中,ZooKeeper主要用于實(shí)現(xiàn)HA(High Availability),這部分邏輯主要集中在Hadoop Common的HA模塊中,HDFS的NameNode與YARN的ResouceManager都是基于此HA模塊來(lái)實(shí)現(xiàn)自己的HA功能的。同時(shí),在YARN中又特別提供了ZooKeeper來(lái)存儲(chǔ)應(yīng)用的運(yùn)行狀態(tài)。

2.2 HBase

HBase,全程Hadoop Database,是Google Bigtable的開源實(shí)現(xiàn),是一個(gè)基于Hadoop文件系統(tǒng)設(shè)計(jì)的面向海量數(shù)據(jù)的高可靠性、高性能、面向列、可伸縮的分布式存儲(chǔ)系統(tǒng),利用HBase技術(shù)可以在廉價(jià)的PC服務(wù)器上搭建起大規(guī)模結(jié)構(gòu)化的存儲(chǔ)集群。

HBase在實(shí)現(xiàn)上嚴(yán)格遵守了Google BigTable論文的設(shè)計(jì)思想。BigTable使用Chubby來(lái)負(fù)責(zé)分布式狀態(tài)的協(xié)調(diào),這是Google實(shí)現(xiàn)的一種基于Paxos算法的分布式鎖服務(wù),而HBase則采用了開源的ZooKeeper服務(wù)來(lái)完成對(duì)整個(gè)系統(tǒng)的分布式協(xié)調(diào)工作。

2.3 Kafka

Kafka是一個(gè)吞吐量極高的分布式消息系統(tǒng),其整體設(shè)計(jì)師典型的發(fā)布與訂閱模式系統(tǒng)。在Kafka集群中,沒(méi)有“中心主節(jié)點(diǎn)”的概念,集群中所有的服務(wù)器都是對(duì)等的,因此可以在不做任何配置更改的情況下實(shí)現(xiàn)服務(wù)器的添加和刪除,同樣,消息的生產(chǎn)者和消費(fèi)者也能做到隨意重啟和機(jī)器的上下線。在Kafka的設(shè)計(jì)中,選擇使用ZooKeeper來(lái)進(jìn)行所有Broker的管理。

Kafka使用ZooKeeper作為其分布式協(xié)調(diào)框架,很好地將消息生成、消息存儲(chǔ)和消息消費(fèi)有機(jī)結(jié)合起來(lái),同時(shí)借助ZooKeeper,Kafka能在保持包括生產(chǎn)者、消費(fèi)者和Broker在內(nèi)的所有組件無(wú)狀態(tài)的情況下,建立起生產(chǎn)者和消費(fèi)者之間的訂閱關(guān)系,并實(shí)現(xiàn)了生產(chǎn)者和消費(fèi)者的負(fù)載均衡。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容