ZooKeeper(二)ZooKeeper能做什么?
命名服務(Name Service)
主要是作為分布式命名服務,通過調(diào)用zk的create node api,能夠很容易創(chuàng)建一個全局唯一的path,這個path就可以作為一個名稱。這些paht具有層級結(jié)構(gòu),非常便于理解和管理。
配置管理(Configuration Management)
配置的管理在分布式應用環(huán)境中很常見,例如同一個應用系統(tǒng)需要多臺Server 運行,但該應用系統(tǒng)的某些配置項是相同的,如果要修改這些相同的配置項,那么就必須同時修改每臺運行該系統(tǒng)的Server上的配置,這樣非常麻煩而且容易出錯。
像這樣的配置信息完全可以交給 Zookeeper 來管理,將配置信息保存在 Zookeeper 的某個節(jié)點中,然后將所有需要修改的應用機器監(jiān)控配置信息的狀態(tài),一旦配置信息發(fā)生變化,每臺應用機器就會收到 Zookeeper 的通知,然后從 Zookeeper 獲取新的配置信息應用到系統(tǒng)中。
配置管理示意圖:
集群管理(Group Membership)
ZooKeeper的集群管理主要在兩點:監(jiān)控集群是否有機器退出和加入、選舉master。
對于第一點,過去的做法通常是:監(jiān)控系統(tǒng)通過某種手段(比如ping)定時檢測每個機器,或者每個機器自己定時向監(jiān)控系統(tǒng)匯報“我還活著”。 這種做法可行,但是存在兩個比較明顯的問題:1)集群中機器有變動的時候,牽連修改的東西比較多。2)有一定的延時。
利用ZooKeeper有兩個特性,就可以實時另一種集群機器存活性監(jiān)控系統(tǒng):所有機器約定在父目錄(比如/GroupMembers)下創(chuàng)建臨時目錄節(jié)點,然后監(jiān)聽父目錄節(jié)點的子節(jié)點變化消息。一旦有機器掛掉,該機器與 zookeeper的連接斷開,其所創(chuàng)建的臨時目錄節(jié)點被刪除,所有其他機器都收到通知:某個目錄被刪除,即有一臺機器掛掉了。新機器加入也是類似。
對于第二點,在分布式環(huán)境中,相同的業(yè)務應用分布在不同的機器上,有些業(yè)務邏輯(例如一些耗時的計算,網(wǎng)絡(luò)I/O處理),往往只需要讓整個集群中的某一臺機器進行執(zhí)行, 其余機器可以共享這個結(jié)果,這樣可以大大減少重復勞動,提高性能,于是這個master選舉便是這種場景下的碰到的主要問題。利用ZooKeeper的強一致性,能夠保證在分布式高并發(fā)情況下節(jié)點創(chuàng)建的全局唯一性,即:同時有多個客戶端請求創(chuàng)建 ·/currentMaster 節(jié)點,最終一定只有一個客戶端請求能夠創(chuàng)建成功。利用這個特性,就能很輕易的在分布式環(huán)境中進行集群選取了。
另外,這種場景演化一下,就是動態(tài)master選舉。這就要用到EPHEMERAL_SEQUENTIAL類型節(jié)點的特性了。
動態(tài)master選舉可以用來解決分布式系統(tǒng)中的單點故障。什么是分布式系統(tǒng)中的單點故障:通常分布式系統(tǒng)采用主從模式,就是一個主控機連接多個處理節(jié)點。主節(jié)點負責分發(fā)任務,從節(jié)點負責處理任務,當我們的主節(jié)點發(fā)生故障時,那么整個系統(tǒng)就都癱瘓了,那么我們把這種故障叫作<font color=#D2691E>單點故障</font>。
傳統(tǒng)的解決方案是采用一個備用節(jié)點,這個備用節(jié)點定期給當前主節(jié)點發(fā)送ping包,主節(jié)點收到ping包以后向備用節(jié)點發(fā)送回復Ack,當備用節(jié)點收到回復的時候就會認為當前主節(jié)點還活著,讓它繼續(xù)提供服務。如圖所示:
當主節(jié)點掛了,這時候備用節(jié)點收不到回復了,然后他就認為主節(jié)點掛了接替他成為主節(jié)點:
但是這種方式就是有一個隱患,就是網(wǎng)絡(luò)問題,來看一網(wǎng)絡(luò)問題會造成什么后果,如下圖所示:
也就是說我們的主節(jié)點的并沒有掛,只是在回復的時候網(wǎng)絡(luò)發(fā)生故障,這樣我們的備用節(jié)點同樣收不到回復,就會認為主節(jié)點掛了,然后備用節(jié)點將他的Master實例啟動起來,這樣我們的分布式系統(tǒng)當中就有了兩個主節(jié)點也就是---雙Master, 出現(xiàn)雙Master以后從節(jié)點就會將它所做的事一部分匯報給了主節(jié)點,一部分匯報給了備用節(jié)點,這樣服務就全亂了。為了防止出現(xiàn)這種情況,我們引入了 ZooKeeper,它雖然不能避免網(wǎng)絡(luò)故障,但它能夠保證每時每刻只有一個Master。
具體方案是:
1.master啟動
在引入了Zookeeper以后我們啟動了兩個主節(jié)點,"主節(jié)點-A"和"主節(jié)點-B"他們啟動以后,都向ZooKeeper去注冊一個節(jié)點(EPHEMERAL_SEQUENTIAL類型節(jié)點)。我們假設(shè)"主節(jié)點-A"鎖注冊地節(jié)點是"master-00001","主節(jié)點-B"注冊的節(jié)點是"master-00002",注冊完以后進行選舉,規(guī)定選舉序號最小的節(jié)點作為為主節(jié)點,也就是我們的"主節(jié)點-A"將會成為主節(jié)點,然后"主節(jié)點-B"將成為一個備用節(jié)點。通過這種方式就完成了對兩個Master進程的調(diào)度。
2.master故障
如果"主節(jié)點-A"掛了,這時候他所注冊的節(jié)點將被自動刪除,ZooKeeper會自動感知節(jié)點的變化,然后再次發(fā)出選舉,這時候"主節(jié)點-B"將在選舉中獲勝,替代"主節(jié)點-A"成為主節(jié)點。
3.master恢復
如果主節(jié)點恢復了,他會再次向ZooKeeper注冊一個節(jié)點,這時候他注冊的節(jié)點將會是"master-00003",ZooKeeper會感知節(jié)點的變化再次發(fā)動選舉,這時候"主節(jié)點-B"在選舉中會再次獲勝繼續(xù)擔任"主節(jié)點","主節(jié)點-A"會擔任備用節(jié)點。
分布式鎖
什么是分布式鎖?
- 一般的鎖:一般我們說的鎖是單進程多線程的鎖,在多線程并發(fā)編程中,用于線程之間的數(shù)據(jù)同步,保護共享資源的訪問
- 分布式鎖:分布式鎖指的是在分布式環(huán)境下,保護跨進程,跨主機,跨網(wǎng)絡(luò)的共享資源,實現(xiàn)互斥訪問,保證一致性
分布式鎖主要得益于ZooKeeper為我們保證了數(shù)據(jù)的一致性,即用戶只要完全相信每時每刻,zk集群中任意節(jié)點(一臺zk server)上的相同Znode的數(shù)據(jù)是一定都是相同的。
分布式鎖的架構(gòu)圖:
解釋: 左邊的整個區(qū)域表示一個ZooKeeper集群,locker是ZooKeeper的一個持久節(jié)點,node_1、node_2、node_3是locker這個持久節(jié)點下面的臨時順序節(jié)點。client_1、client_2、client_n表示多個客戶端,Service表示需要互斥訪問的共享資源。
分布式鎖的總體思路
需要獲得鎖的 client 創(chuàng)建一個 EPHEMERAL_SEQUENTIAL 目錄節(jié)點,然后調(diào)用 getChildren方法獲取當前的目錄節(jié)點列表中最小的目錄節(jié)點是不是就是自己創(chuàng)建的目錄節(jié)點,如果正是自己創(chuàng)建的,那么它就獲得了這個鎖,如果不是那么它就調(diào)用 exists(String path, boolean watch) 方法并監(jiān)控 Zookeeper 上目錄節(jié)點列表的變化,一直到自己創(chuàng)建的節(jié)點是列表中最小編號的目錄節(jié)點,從而獲得鎖,釋放鎖很簡單,只要刪除前面它自己所創(chuàng)建的目錄節(jié)點就行了。
分布式隊列
Zookeeper 可以處理兩種類型的隊列:
第一類,和分布式鎖服務中的控制時序場景基本原理一致,入列有編號,出列按編號。實現(xiàn)起來也非常簡單,就是在特定的目錄下創(chuàng)建 SEQUENTIAL 類型的子目錄/queue_i,這樣就能保證所有成員加入隊列時都是有編號的,出隊列時通過getChildren( )方法可以返回當前所有的隊列中的元素,然后消費其中最小的一個,這樣就能保證 FIFO。
第二類,通常可以在/queue這個Znode下預先建立一個/queue/num節(jié)點,并且賦值為n(或者直接給/queue賦值為n),表示隊列大小,之后每次有隊列成員加入后,就判斷下是否已經(jīng)到達隊列大小,決定是否可以開始執(zhí)行 了。這種用法的典型場景是,分布式環(huán)境中,一個大任務Task A,需要在很多子任務完成(或條件就緒)情況下才能進行。這個時候,凡是其中一個子任務完成(就緒),那么就去 /taskList下建立自己的臨時時序節(jié)點(CreateMode.EPHEMERAL_SEQUENTIAL),當/taskList發(fā)現(xiàn)自己下面的子節(jié)點滿足指定個數(shù),就可以進行下一步處理了(比如創(chuàng)建一個/task/start節(jié)點)。
總結(jié)
以上是生活随笔為你收集整理的ZooKeeper(二)ZooKeeper能做什么?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用不同显卡训练gan的区别_面霜质地这么
- 下一篇: vue如何实现单页缓存方案分析