首頁常見問題正文

Zookeeper如何管理集群?【大數(shù)據(jù)知識】

更新時間:2023-01-14 來源:黑馬程序員 瀏覽量:

IT培訓(xùn)班

隨著分布式系統(tǒng)規(guī)模的日益擴(kuò)大,集群中的機(jī)器規(guī)模也隨之變大,那如何更好地進(jìn)行集群管理也顯得越來越重要了。所謂集群管理,包括集群監(jiān)控與集群控制兩大塊,前者側(cè)重對集群運(yùn)行時狀態(tài)的收集,后者則是對集群進(jìn)行操作與控制。

在日常開發(fā)和運(yùn)維過程中,我們經(jīng)常會有類似于如下的需求:

·如何快速的統(tǒng)計出當(dāng)前生產(chǎn)環(huán)境下一共有多少臺機(jī)器

·如何快速的獲取到機(jī)器上下線的情況

·如何實時監(jiān)控集群中每臺主機(jī)的運(yùn)行時狀態(tài)

在傳統(tǒng)的基于Agent的分布式集群管理體系中,都是通過在集群中的每臺機(jī)器上部署一個 Agent,由這個 Agent 負(fù)責(zé)主動向指定的一個監(jiān)控中心系統(tǒng)(監(jiān)控中心系統(tǒng)負(fù)責(zé)將所有數(shù)據(jù)進(jìn)行集中處理,形成一系列報表,并負(fù)責(zé)實時報警,以下簡稱“監(jiān)控中心”)匯報自己所在機(jī)器的狀態(tài)。在集群規(guī)模適中的場景下,這確實是一種在生產(chǎn)實踐中廣泛使用的解決方案,能夠快速有效地實現(xiàn)分布式環(huán)境集群監(jiān)控,但是一旦系統(tǒng)的業(yè)務(wù)場景增多,集群規(guī)模變大之后,該解決方案的弊端也就顯現(xiàn)出來了。

大規(guī)模升級困難

以客戶端形式存在的 Agent,在大規(guī)模使用后,一旦遇上需要大規(guī)模升級的情況,就非常麻煩,在升級成本和升級進(jìn)度的控制上面臨巨大的挑戰(zhàn)。

統(tǒng)一的Agent無法滿足多樣的需求

對于機(jī)器的CPU使用率、負(fù)載(Load)、內(nèi)存使用率、網(wǎng)絡(luò)吞吐以及磁盤容量等機(jī)器基本的物理狀態(tài),使用統(tǒng)一的Agent來進(jìn)行監(jiān)控或許都可以滿足。但是,如果需要深入應(yīng)用內(nèi)部,對一些業(yè)務(wù)狀態(tài)進(jìn)行監(jiān)控,例如,在一個分布式消息中間件中,希望監(jiān)控到每個消費(fèi)者對消息的消費(fèi)狀態(tài);或者在一個分布式任務(wù)調(diào)度系統(tǒng)中,需要對每個機(jī)器上任務(wù)的執(zhí)行情況進(jìn)行監(jiān)控。很顯然,對于這些業(yè)務(wù)耦合緊密的監(jiān)控需求,不適合由一個統(tǒng)一的Agent來提供。

編程語言多樣性

隨著越來越多編程語言的出現(xiàn),各種異構(gòu)系統(tǒng)層出不窮。如果使用傳統(tǒng)的Agent方式,那么需要提供各種語言的 Agent 客戶端。另一方面,“監(jiān)控中心”在對異構(gòu)系統(tǒng)的數(shù)據(jù)進(jìn)行整合上面臨巨大挑戰(zhàn)。

Zookeeper的兩大特性:

1.客戶端如果對Zookeeper的數(shù)據(jù)節(jié)點(diǎn)注冊Watcher監(jiān)聽,那么當(dāng)該數(shù)據(jù)節(jié)點(diǎn)的內(nèi)容或是其子節(jié)點(diǎn)列表發(fā)生變更時,Zookeeper服務(wù)器就會向訂閱的客戶端發(fā)送變更通知。

2.對在Zookeeper上創(chuàng)建的臨時節(jié)點(diǎn),一旦客戶端與服務(wù)器之間的會話失效,那么臨時節(jié)點(diǎn)也會被自動刪除

利用其兩大特性,可以實現(xiàn)集群機(jī)器存活監(jiān)控系統(tǒng),若監(jiān)控系統(tǒng)在/clusterServers節(jié)點(diǎn)上注冊一個Watcher監(jiān)聽,那么但凡進(jìn)行動態(tài)添加機(jī)器的操作,就會在/clusterServers節(jié)點(diǎn)下創(chuàng)建一個臨時節(jié)點(diǎn):/clusterServers/[Hostname],這樣,監(jiān)控系統(tǒng)就能夠?qū)崟r監(jiān)測機(jī)器的變動情況。

下面通過分布式日志收集系統(tǒng)這個典型應(yīng)用來學(xué)習(xí)Zookeeper如何實現(xiàn)集群管理。

分布式日志收集系統(tǒng):

分布式日志收集系統(tǒng)的核心工作就是收集分布在不同機(jī)器上的系統(tǒng)日志,在這里我們重點(diǎn)來看分布式日志系統(tǒng)(以下簡稱“日志系統(tǒng)”)的收集器模塊。

在一個典型的日志系統(tǒng)的架構(gòu)設(shè)計中,整個日志系統(tǒng)會把所有需要收集的日志機(jī)器(我們以“日志源機(jī)器”代表此類機(jī)器)分為多個組別,每個組別對應(yīng)一個收集器,這個收集器其實就是一個后臺機(jī)器(我們以“收集器機(jī)器”代表此類機(jī)器),用于收集日志

· 變化的日志源機(jī)器

在生產(chǎn)環(huán)境中,伴隨著機(jī)器的變動,每個應(yīng)用的機(jī)器幾乎每天都是在變化的(機(jī)器硬件問題、擴(kuò)容、機(jī)房遷移或是網(wǎng)絡(luò)問題等都會導(dǎo)致一個應(yīng)用的機(jī)器變化),也就是說每個組別中的日志源機(jī)器通常是在不斷變化的。

· 變化的收集器機(jī)器

日志收集系統(tǒng)自身也會有機(jī)器的變更或擴(kuò)容,于是會出現(xiàn)新的收集器機(jī)器加入或是老的收集器機(jī)器退出的情況。

無論是日志源機(jī)器還是收集器機(jī)器的變更,最終都可以歸結(jié)為如何快速、合理、動態(tài)地為每個收集器分配對應(yīng)的日志源機(jī)器。這也成為了整個日志系統(tǒng)正確穩(wěn)定運(yùn)轉(zhuǎn)的前提,也是日志收集過程中最大的技術(shù)挑戰(zhàn)之一,在這種情況下,我們就可以引入zookeeper了,下面我們就來看ZooKeeper在這個場景中的使用。

使用Zookeeper的場景步驟如下

① 注冊收集器機(jī)器

使用ZooKeeper來進(jìn)行日志系統(tǒng)收集器的注冊,典型做法是在ZooKeeper上創(chuàng)建一個節(jié)點(diǎn)作為收集器的根節(jié)點(diǎn),例如/logs/collector(下文我們以“收集器節(jié)點(diǎn)”代表該數(shù)據(jù)節(jié)點(diǎn)),每個收集器機(jī)器在啟動的時候,都會在收集器節(jié)點(diǎn)下創(chuàng)建自己的節(jié)點(diǎn),例如/logs/collector/[Hostname]

1604040251848_集群管理.jpg

② 任務(wù)分發(fā)

待所有收集器機(jī)器都創(chuàng)建好自己對應(yīng)的節(jié)點(diǎn)后,系統(tǒng)根據(jù)收集器節(jié)點(diǎn)下子節(jié)點(diǎn)的個數(shù),將所有日志源機(jī)器分成對應(yīng)的若干組,然后將分組后的機(jī)器列表分別寫到這些收集器機(jī)器創(chuàng)建的子節(jié)點(diǎn)(例如/logs/collector/host1)上去。這樣一來,每個收集器機(jī)器都能夠從自己對應(yīng)的收集器節(jié)點(diǎn)上獲取日志源機(jī)器列表,進(jìn)而開始進(jìn)行日志收集工作。

③ 狀態(tài)匯報

完成收集器機(jī)器的注冊以及任務(wù)分發(fā)后,我們還要考慮到這些機(jī)器隨時都有掛掉的可能。因此,針對這個問題,我們需要有一個收集器的狀態(tài)匯報機(jī)制:每個收集器機(jī)器在創(chuàng)建完自己的專屬節(jié)點(diǎn)后,還需要在對應(yīng)的子節(jié)點(diǎn)上創(chuàng)建一個狀態(tài)子節(jié)點(diǎn),例如/logs/collector/host1/status,每個收集器機(jī)器都需要定期向該節(jié)點(diǎn)寫入自己的狀態(tài)信息。我們可以把這種策略看作是一種心跳檢測機(jī)制,通常收集器機(jī)器都會在這個節(jié)點(diǎn)中寫入日志收集進(jìn)度信息。日志系統(tǒng)根據(jù)該狀態(tài)子節(jié)點(diǎn)的最后更新時間來判斷對應(yīng)的收集器機(jī)器是否存活。

④ 動態(tài)分配

如果收集器機(jī)器掛掉或是擴(kuò)容了,就需要動態(tài)地進(jìn)行收集任務(wù)的分配。在運(yùn)行過程中,日志系統(tǒng)始終關(guān)注著/logs/collector這個節(jié)點(diǎn)下所有子節(jié)點(diǎn)的變更,一旦檢測到有收集器機(jī)器停止匯報或是有新的收集器機(jī)器加入,就要開始進(jìn)行任務(wù)的重新分配。無論是針對收集器機(jī)器停止匯報還是新機(jī)器加入的情況,日志系統(tǒng)都需要將之前分配給該收集器的所有任務(wù)進(jìn)行轉(zhuǎn)移。為了解決這個問題,通常有兩種做法:

· 全局動態(tài)分配

這是一種簡單粗暴的做法,在出現(xiàn)收集器機(jī)器掛掉或是新機(jī)器加入的時候,日志系統(tǒng)需要根據(jù)新的收集器機(jī)器列表,立即對所有的日志源機(jī)器重新進(jìn)行一次分組,然后將其分配給剩下的收集器機(jī)器。

· 局部動態(tài)分配

全局動態(tài)分配方式雖然策略簡單,但是存在一個問題:一個或部分收集器機(jī)器的變更,就會導(dǎo)致全局動態(tài)任務(wù)的分配,影響面比較大,因此風(fēng)險也就比較大。所謂局部動態(tài)分配,顧名思義就是在小范圍內(nèi)進(jìn)行任務(wù)的動態(tài)分配。在這種策略中,每個收集器機(jī)器在匯報自己日志收集狀態(tài)的同時,也會把自己的負(fù)載匯報上去。請注意,這里提到的負(fù)載并不僅僅只是簡單地指機(jī)器CPU負(fù)載(Load),而是一個對當(dāng)前收集器任務(wù)執(zhí)行的綜合評估,這個評估算法和ZooKeeper本身并沒有太大的關(guān)系,這里不再贅述。

在這種策略中,如果一個收集器機(jī)器掛了,那么日志系統(tǒng)就會把之前分配給這個機(jī)器的任務(wù)重新分配到那些負(fù)載較低的機(jī)器上去。同樣,如果有新的收集器機(jī)器加入,會從那些負(fù)載高的機(jī)器上轉(zhuǎn)移部分任務(wù)給這個新加入的機(jī)器。

上述步驟已經(jīng)完整的說明了整個日志收集系統(tǒng)的工作流程,其中有兩點(diǎn)注意事項:

①節(jié)點(diǎn)類型

在/logs/collector節(jié)點(diǎn)下創(chuàng)建臨時節(jié)點(diǎn)可以很好的判斷機(jī)器是否存活,但是,若機(jī)器掛了,其節(jié)點(diǎn)會被刪除,記錄在節(jié)點(diǎn)上的日志源機(jī)器列表也被清除,所以需要選擇持久節(jié)點(diǎn)來標(biāo)識每一臺機(jī)器,同時在節(jié)點(diǎn)下分別創(chuàng)建/logs/collector/[Hostname]/status節(jié)點(diǎn)來表征每一個收集器機(jī)器的狀態(tài),這樣,既能實現(xiàn)對所有機(jī)器的監(jiān)控,同時機(jī)器掛掉后,依然能夠?qū)⒎峙淙蝿?wù)還原。

② 日志系統(tǒng)節(jié)點(diǎn)監(jiān)聽

若采用Watcher機(jī)制,那么通知的消息量的網(wǎng)絡(luò)開銷非常大,需要采用日志系統(tǒng)主動輪詢收集器節(jié)點(diǎn)的策略,這樣可以節(jié)省網(wǎng)絡(luò)流量,但是存在一定的延時。


分享到:
在線咨詢 我要報名
和我們在線交談!