分布式高并發(fā),ZooKeeper架構(gòu)及原理

2021-02-14    分類: 網(wǎng)站建設(shè)

Zookeeper是分布式一致性問題的工業(yè)解決方案,是Apache Hadoop下解決分布式一致性的一個(gè)組件,后被分離出來成為Apache的頂級(jí)項(xiàng)目。

工程來源:是雅虎公司內(nèi)部項(xiàng)目,據(jù)說雅虎內(nèi)部很多項(xiàng)目都是以動(dòng)物命名,這個(gè)動(dòng)物管理員的名字起的很是形象。

被開源出來后得到開源社區(qū)的快速推進(jìn),服務(wù)端Java語言實(shí)現(xiàn),棒,git有3000+的star:

https://github.com/apache/zookeeper


zookeeper集群結(jié)構(gòu)

集群的角色,比較典型的是Master/Slave(主備模式),zk中的概念跟這個(gè)不一樣,包含Leader、Follower、Observer三個(gè)角色,leader提供讀和寫的能力,follower只對(duì)外提供讀的能力。

會(huì)話(session)

客戶端跟服務(wù)端交互,是先與服務(wù)端建立一個(gè)TCP長(zhǎng)連接,會(huì)話開始,通過心跳檢測(cè)與服務(wù)端保持會(huì)話有效,向服務(wù)端發(fā)送請(qǐng)求和接收響應(yīng)。

zk將所有的數(shù)據(jù)都加載在內(nèi)存一份,同時(shí)有事務(wù)日志文件(持久化文件),服務(wù)端會(huì)定時(shí)dump快照數(shù)據(jù),重啟機(jī)器的時(shí)候會(huì)根據(jù)快照和事務(wù)日志恢復(fù)內(nèi)存數(shù)據(jù)庫的數(shù)據(jù),這跟redis的AOF和RDB概念類似。

zookeeper上的數(shù)據(jù)結(jié)構(gòu)

zk上的數(shù)據(jù)的結(jié)構(gòu)跟linux文件系統(tǒng)很像,是個(gè)樹狀結(jié)構(gòu)


節(jié)點(diǎn)(node)上的信息字段


節(jié)點(diǎn)類型包括:

  • 持久型節(jié)點(diǎn)
  • 順序持久型節(jié)點(diǎn)
  • 臨時(shí)節(jié)點(diǎn)
  • 順序臨時(shí)節(jié)點(diǎn)

其中臨時(shí)節(jié)點(diǎn)特性就是創(chuàng)建它的主體消失后,它就跟著消失了。后續(xù)的應(yīng)用就是利用的節(jié)點(diǎn)的特性實(shí)現(xiàn)的。

事件監(jiān)聽器(watcher)

這個(gè)應(yīng)該是zookeeper最重要的概念之一了,zk允許用戶在特定的節(jié)點(diǎn)(znode)上注冊(cè)watcher,并且在特定事件觸發(fā)的時(shí)候,zk服務(wù)端會(huì)將事件通知到感興趣的客戶端上。

偽集群的搭建:


zoo.cfg 配置文件

  • 拷貝三份文件
  • 修改配置zoo.cfg,區(qū)別出日志目錄和端口號(hào),dataDir文件下添加表示機(jī)器號(hào)的文件myid
  • 集群配置列表,第一個(gè)端口是機(jī)器間業(yè)務(wù)通訊的端口,第二個(gè)端口是用來進(jìn)行l(wèi)eader選舉的端口
  • 分別啟動(dòng)三臺(tái)服務(wù)器

啟動(dòng)成功后,命令行連接zk,可以用指令做些增刪改查的操作

telnet 127.0.0.1 2181

stat:可以看集群的狀態(tài)信息


stat信息

每次事務(wù)操作,會(huì)在dataDir的目錄下的事務(wù)日志,是序列化的二進(jìn)制文件,zookeeper提供了查看事務(wù)日志的工具類LogFormatter


LogFormatter轉(zhuǎn)換后的事務(wù)日志文件

Java客戶端使用

  1. zookeeper自帶的
  2. 開源的客戶端ZkClient,實(shí)現(xiàn)session超時(shí)重連,watcher反復(fù)注冊(cè)的功能,簡(jiǎn)化開發(fā)人員的使用
  3. 開源客戶端Crurator,解決底層的細(xì)節(jié)開發(fā)工作,目前是apache的頂級(jí)項(xiàng)目,是使用最廣泛的zk客戶端。
  4. 提供了可讀性更新的api接口
  5. 提供了各種應(yīng)用場(chǎng)景的抽象封裝(共享鎖服務(wù)、Master選舉機(jī)制,分布式計(jì)數(shù)器等)
  6. guava is to java what cruator is to zookeeper



cruator客戶端例子

zookeeper應(yīng)用場(chǎng)景

利用zookeeper的特性,可以比較方便的構(gòu)建分布式應(yīng)用會(huì)涉及的核心功能,比如:配置中心、命名服務(wù)、分布式協(xié)調(diào)/通知、集群的管理、master選舉、分布式鎖等

以下應(yīng)用基本基于zookeeper的兩大特性實(shí)現(xiàn)

  • 客戶端如果對(duì)zookeeper的一個(gè)數(shù)據(jù)節(jié)點(diǎn)注冊(cè)watcher監(jiān)聽,那么當(dāng)該數(shù)據(jù)節(jié)點(diǎn)的內(nèi)容或其子節(jié)點(diǎn)的列表發(fā)生變更是,zookeeper服務(wù)器就會(huì)想訂閱的客戶端發(fā)送變更通知
  • 對(duì)在zookeeper上創(chuàng)建的臨時(shí)節(jié)點(diǎn)(sequent類型),一旦客戶端與服務(wù)器之間的回話失效,那么臨時(shí)節(jié)點(diǎn)會(huì)被自動(dòng)清除

--配置中心:


配置中心

zookeeper利用推拉結(jié)合的方式,客戶端向服務(wù)端注冊(cè)自己需要關(guān)注的節(jié)點(diǎn),一旦該數(shù)據(jù)發(fā)生變更,那么服務(wù)器就會(huì)向相應(yīng)的客戶端發(fā)送watcher時(shí)間通知。

客戶收到這個(gè)消息通知之后,再主動(dòng)到服務(wù)端獲取最新的數(shù)據(jù)。即回調(diào)的event中包含具體的數(shù)據(jù)。

這個(gè)應(yīng)用的的業(yè)務(wù)員特點(diǎn):

  1. 數(shù)據(jù)不經(jīng)常變化
  2. 數(shù)據(jù)量通常比較小,保存的內(nèi)存里,訪問很快
  3. 配置動(dòng)態(tài)變化,不需要重啟機(jī)器,數(shù)據(jù)變化,會(huì)通知相應(yīng)的客戶端
  4. 集群共享配置一致,比如數(shù)據(jù)庫連接的配置,業(yè)務(wù)的開關(guān),甚至一些數(shù)據(jù)量小,不經(jīng)常變的業(yè)務(wù)數(shù)據(jù)如彈窗文案,活動(dòng)文案也放里邊,用于快速迭代實(shí)現(xiàn)功能。

--命名服務(wù)

利用zookeeper的順序節(jié)點(diǎn),樹形結(jié)構(gòu)的數(shù)據(jù)特點(diǎn),實(shí)現(xiàn)命名服務(wù):

  • 比如RPC框架中,每個(gè)服務(wù)在zookeeper中對(duì)應(yīng)一個(gè)節(jié)點(diǎn)(serviceName),節(jié)點(diǎn)下存放這個(gè)服務(wù)所用到的資源,比如部署的ip列表,接口列表

這樣RPC的客戶端只需要傳對(duì)應(yīng)的服務(wù)名字,和接口,就能找到對(duì)應(yīng)的服務(wù)。

  • 全局唯一id的生成,UUID(通用的唯一標(biāo)識(shí)碼)可以實(shí)現(xiàn),但是他的缺點(diǎn)是:太長(zhǎng),包含32位字符和4個(gè)短線字符串;看不出業(yè)務(wù)含義,不方便排查問題。

使用zookeeper實(shí)現(xiàn):不同的業(yè)務(wù)下創(chuàng)建一個(gè)節(jié)點(diǎn),具體的節(jié)點(diǎn)下用zk的順序節(jié)點(diǎn)(sequent)生成id當(dāng)做這個(gè)業(yè)務(wù)的全局唯一id使用

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

ZooKeeper中特有watcher注冊(cè)與異步通知機(jī)制,能夠很好的實(shí)現(xiàn)分布式環(huán)境下不同系統(tǒng)之間的通知與協(xié)調(diào),實(shí)現(xiàn)對(duì)數(shù)據(jù)變更的實(shí)時(shí)處理。

使用方法通常是不同系統(tǒng)都對(duì)ZK上同一個(gè)znode進(jìn)行注冊(cè),監(jiān)聽znode的變化(包括znode本身內(nèi)容及子節(jié)點(diǎn)的),其中一個(gè)系統(tǒng)update了znode,那么另一個(gè)系統(tǒng)能夠收到通知,并作出相應(yīng)處理。

應(yīng)用:

心跳檢測(cè)機(jī)制:傳統(tǒng)的方式是ping,復(fù)雜的話是建立長(zhǎng)連接檢測(cè)系統(tǒng)和被檢測(cè)系統(tǒng)之間并不直接關(guān)聯(lián)起來,而是通過zookeeper上某個(gè)節(jié)點(diǎn)關(guān)聯(lián),大大減少系統(tǒng)耦合

系統(tǒng)調(diào)度模式:某系統(tǒng)由控制臺(tái)和推送系統(tǒng)兩部分組成,控制臺(tái)的職責(zé)是控制推送系統(tǒng)進(jìn)行相應(yīng)的推送工作。

管理人員在控制臺(tái)作的一些操作,實(shí)際上是修改了ZK上某些節(jié)點(diǎn)的狀態(tài),而ZK就把這些變化通知給他們注冊(cè)Watcher的客戶端,即推送系統(tǒng)。于是,作出相應(yīng)的推送任務(wù)

作匯報(bào)模式:一些類似于任務(wù)分發(fā)系統(tǒng),子任務(wù)啟動(dòng)后,到ZK來注冊(cè)一個(gè)臨時(shí)節(jié)點(diǎn),并且定時(shí)將自己的進(jìn)度進(jìn)行匯報(bào)(將進(jìn)度寫回這個(gè)臨時(shí)節(jié)點(diǎn))

總之,使用zookeeper來進(jìn)行分布式通知和協(xié)調(diào)能夠大大降低系統(tǒng)之間的耦合。

--分布式鎖

這個(gè)應(yīng)用主要得益于ZooKeeper為我們保證了數(shù)據(jù)的強(qiáng)一致性

即用戶只要完全相信每時(shí)每刻,zk集群中任意節(jié)點(diǎn)(一個(gè)zk server)上的相同znode的數(shù)據(jù)是一定是相同的。

一個(gè)節(jié)點(diǎn)要么創(chuàng)建成功,要么失敗,并且只由一個(gè)客戶端創(chuàng)建。

獨(dú)占鎖:

保持獨(dú)占,就是所有試圖來獲取這個(gè)鎖的客戶端,最終只有一個(gè)可以成功獲得這把鎖。

通常的做法是把ZK上的一個(gè)znode看作是一把鎖,通過create znode的方式來實(shí)現(xiàn)。所有客戶端都去創(chuàng)建/distribute_lock節(jié)點(diǎn),最終成功創(chuàng)建的那個(gè)客戶端也即擁有了這把鎖。

共享時(shí)序控制鎖:

Zookeeper很容易實(shí)現(xiàn)這個(gè)功能,實(shí)現(xiàn)方式是需要獲得鎖的Server,創(chuàng)建一個(gè)EPHEMERAL_SEQUENTIAL目錄節(jié)點(diǎn)。

然后調(diào)用getChildren方法獲取當(dāng)前的目錄節(jié)點(diǎn)列表中最小的目錄節(jié)點(diǎn)是不是就是自己創(chuàng)建的目錄節(jié)點(diǎn)。

如果正是自己創(chuàng)建的,那么它就獲得了這個(gè)鎖,如果不是,那么它就調(diào)用exists(String path, boolean watch)方法,并監(jiān)控Zookeeper上目錄節(jié)點(diǎn)列表的變化,一直到自己創(chuàng)建的節(jié)點(diǎn)是列表中最小編號(hào)的目錄節(jié)點(diǎn),從而獲得鎖。

釋放鎖很簡(jiǎn)單,只要?jiǎng)h除前面它自己所創(chuàng)建的目錄節(jié)點(diǎn)就行了。

--master選舉


master選舉應(yīng)用圖


有個(gè)容易理解的方案,依靠關(guān)系型數(shù)據(jù)庫主鍵的特性,集群的機(jī)器同時(shí)往一張表里插入數(shù)據(jù),數(shù)據(jù)庫會(huì)自動(dòng)進(jìn)行主鍵沖突檢查,可以選擇插入成功的客戶端作為master

這種方式存在一個(gè)問題就是,master機(jī)器掛了,沒有人通知

zk實(shí)現(xiàn)可以方便做到這一點(diǎn):zk的創(chuàng)建節(jié)點(diǎn)api接口,具有強(qiáng)一致性,能夠保證客戶端并發(fā)創(chuàng)建的時(shí)候,最終一定只有一個(gè)客戶端創(chuàng)建成功。

  • 客戶端集群每天定時(shí)往/master_election/(當(dāng)天日期)2017-03-24/binding創(chuàng) 建臨時(shí)節(jié)點(diǎn),只有一個(gè)成功,為master
  • 創(chuàng)建失敗的在/master_election/(當(dāng)天日期)2017-03-24 注冊(cè)監(jiān)聽事件,當(dāng)master掛了,其余機(jī)器收到通知,重新進(jìn)行選舉

--集群管理

應(yīng)用舉例:集群機(jī)器存活性監(jiān)控系統(tǒng),例如:

監(jiān)控系統(tǒng)在/clusterServers節(jié)點(diǎn)注冊(cè)一個(gè)watcher監(jiān)聽,那么但凡進(jìn)行動(dòng)態(tài)添加機(jī)器的操作,就在/clusterServers下創(chuàng)建一個(gè)臨時(shí)節(jié)點(diǎn), /clusterServers/ip。

這樣監(jiān)控系統(tǒng)就能夠?qū)崟r(shí)的檢測(cè)到機(jī)器的變動(dòng),通過getChild方法獲取所有的臨時(shí)節(jié)點(diǎn),來判斷增加的機(jī)器。

當(dāng)有機(jī)器down調(diào)或者手動(dòng)下線,相應(yīng)臨時(shí)節(jié)點(diǎn)會(huì)消失,監(jiān)控系統(tǒng)也會(huì)接收到,來處理監(jiān)控服務(wù)的具體業(yè)務(wù)

具體服務(wù)器部署agent實(shí)現(xiàn)

zookeeper的HA設(shè)計(jì)實(shí)現(xiàn)

以上說了那么多犀利實(shí)用的應(yīng)用場(chǎng)景,它們依賴zookeeper,說明這些應(yīng)用服務(wù)的高可用性依賴的zookeeper本身的HA。

zk的選舉算法

算法協(xié)議zab協(xié)議,“少數(shù)服從多數(shù)”協(xié)議一種

3.4.0版本之后Zookeeper只保留了TCP版本的FastLeaderElection選舉算法

分析選舉算法前,先熟悉了解下zk的一些術(shù)語定義解釋:

  • SID:服務(wù)器ID,在集群的配置文件里配置
  • ZXID:是一個(gè)事務(wù)ID,用來唯一標(biāo)示一次服務(wù)器狀態(tài)變更,集群中每臺(tái)機(jī)器上的ZXID可能不一樣
  • Vote:投票選舉,當(dāng)集群中機(jī)器發(fā)現(xiàn)自己無法檢測(cè)到leader的時(shí)候,開始嘗試進(jìn)行投票
  • Quorum:過半機(jī)器數(shù), quorum=(集群機(jī)器數(shù))n/2+1,比如集群數(shù)量是3, quorum=2
集群數(shù)量是4,quorum=2,集群數(shù)量是5,quorum=3

當(dāng)哪些情況發(fā)生時(shí)會(huì)出發(fā)leader重新選舉呢?

當(dāng)zk的一臺(tái)服務(wù)器出現(xiàn)以下兩種情況的時(shí)候,會(huì)進(jìn)入leader選舉流程

  1. 加機(jī)器,服務(wù)器初始化
  2. 服務(wù)器運(yùn)行期間無法和leader通信,leader所在服務(wù)器down掉了

對(duì)于第一種情況,即已經(jīng)存在一臺(tái)leader服務(wù)器,當(dāng)改機(jī)器試圖去選舉leader的時(shí)候,會(huì)被告知當(dāng)前服務(wù)器的leader信息,對(duì)于該機(jī)器僅僅需要和leader建立連接,并進(jìn)行狀態(tài)同步即可

主要看下第二種情況:

有兩種情況導(dǎo)致集群不存在leader,一個(gè)是集群剛啟動(dòng)初始化的時(shí)候,另一種情況是運(yùn)行期間leader所在服務(wù)器掛了。

無論哪種情況集群所有集群都處在一個(gè)找leader的狀態(tài),稱作Looking狀態(tài),開始想其他機(jī)器發(fā)送消息投票

開始leader選舉投票的協(xié)議規(guī)則是怎樣呢?

  • 投票的消息包含(SID,ZXID)
  • 一開始試圖投自己,把投票消息廣播出去
  • 先比較ZXID,選擇ZXID大的
  • ZXID相等的,比較SID,選擇SID大的
  • 如果自己的值大于別的服務(wù)器廣播來的消息,投票不做變更
  • 反正,更換投票,開始第二輪投票,廣播出去投票信息
  • 每輪結(jié)束統(tǒng)計(jì)投票,如果一臺(tái)服務(wù)器收到超過半數(shù)的相同投票,那個(gè)這個(gè)服務(wù)器對(duì)用的SID機(jī)器為L(zhǎng)eader


5臺(tái)機(jī)器宕機(jī)兩臺(tái)后,leader選舉的過程圖示


因此,一個(gè)錯(cuò)誤的認(rèn)識(shí),為了使zookeeper集群能順利的選出leader,必須將zookeeper集群的服務(wù)器數(shù)部署為奇數(shù)。

從上邊例子能看出來部署任意臺(tái)機(jī)器都能夠正常選舉運(yùn)行。部署奇數(shù)臺(tái)是官方給的建議,因?yàn)槠鏀?shù)和奇數(shù)+1的容災(zāi)能力是一樣的。比如:

5臺(tái)服務(wù)器,能夠?qū)?臺(tái)機(jī)器掛掉的情況進(jìn)程容災(zāi)

6臺(tái)服務(wù)器,能夠?qū)?臺(tái)機(jī)器掛掉的情況進(jìn)程容災(zāi),如果掛掉3臺(tái),剩下的機(jī)器就無法實(shí)現(xiàn)過半了。

網(wǎng)站名稱:分布式高并發(fā),ZooKeeper架構(gòu)及原理
網(wǎng)站路徑:http://www.muchs.cn/news12/100862.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)、全網(wǎng)營(yíng)銷推廣、網(wǎng)站建設(shè)、微信公眾號(hào)、App設(shè)計(jì)、定制網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作