更新時間:2020-10-30 來源:黑馬程序員 瀏覽量:
Master選舉是一個在分布式系統中非常常見的應用場景。分布式最核心的特性就是能夠將具有獨立計算能力的系統單元部署在不同的機器上,構成一個完整的分布式系統。而與此同時,實際場景中往往也需要在這些分布在不同機器上的獨立系統單元中選出一個所謂的“老大”,在計算機中,我們稱之為Master。
在分布式系統中,Master往往用來協調集群中其他系統單元,具有對分布式系統狀態變更的決定權。例如,在一些讀寫分離的應用場景中,客戶端的寫請求往往是由 Master來處理的;而在另一些場景中,Master則常常負責處理一些復雜的邏輯,并將處理結果同步給集群中其他系統單元。Master選舉可以說是ZooKeeper最典型的應用場景了,接下來,我們就結合“一種海量數據處理與共享模型”這個具體例子來看看 ZooKeeper在集群Master選舉中的應用場景。
在分布式環境中,經常會碰到這樣的應用場景:集群中的所有系統單元需要對前端業務提供數據,比如一個商品
ID,或者是一個網站輪播廣告的廣告
ID(通常出現在一些廣告投放系統中)等,而這些商品ID或是廣告ID往往需要從一系列的海量數據處理中計算得到——這通常是一個非常耗費 I/O 和
CPU資源的過程。鑒于該計算過程的復雜性,如果讓集群中的所有機器都執行這個計算邏輯的話,那么將耗費非常多的資源。一種比較好的方法就是只讓集群中的部分,甚至只讓其中的一臺機器去處理數據計算,一旦計算出數據結果,就可以共享給整個集群中的其他所有客戶端機器,這樣可以大大減少重復勞動,提升性能。 這里我們以一個簡單的廣告投放系統后臺場景為例來講解這個模型。
整個系統大體上可以分成客戶端集群、分布式緩存系統、海量數據處理總線和 ZooKeeper四個部分
首先我們來看整個系統的運行機制。圖中的Client集群每天定時會通過ZooKeeper來實現Master選舉。選舉產生Master客戶端之后,這個Master就會負責進行一系列的海量數據處理,最終計算得到一個數據結果,并將其放置在一個內存/數據庫中。同時,Master還需要通知集群中其他所有的客戶端從這個內存/數據庫中共享計算結果。
接下去,我們將重點來看 Master 選舉的過程,首先來明確下 Master 選舉的需求:在集群的所有機器中選舉出一臺機器作為Master。針對這個需求,通常情況下,我們可以選擇常見的關系型數據庫中的主鍵特性來實現:集群中的所有機器都向數據庫中插入一條相同主鍵 ID 的記錄,數據庫會幫助我們自動進行主鍵沖突檢查,也就是說,所有進行插入操作的客戶端機器中,只有一臺機器能夠成功——那么,我們就認為向數據庫中成功插入數據的客戶端機器成為Master。
借助數據庫的這種方案確實可行,依靠關系型數據庫的主鍵特性能夠很好地保證在集群中選舉出唯一的一個Master。但是我們需要考慮的另一個問題是,如果當前選舉出的Master掛了,那么該如何處理?誰來告訴我Master掛了呢?顯然,關系型數據庫沒法通知我們這個事件。那么,如果使用ZooKeeper是否可以做到這一點呢? 那在之前,我們介紹了ZooKeeper創建節點的API接口,其中一個重要特性便是:利用ZooKeeper的強一致性,能夠很好保證在分布式高并發情況下節點的創建一定能夠保證全局唯一性,即ZooKeeper將會保證客戶端無法重復創建一個已經存在的數據節點。也就是說,如果同時有多個客戶端請求創建同一個節點,那么最終一定只有一個客戶端請求能夠創建成功。利用這個特性,就能很容易地在分布式環境中進行Master選舉了。
在這個系統中,首先會在 ZooKeeper
上創建一個日期節點,例如“2020-11-11
客戶端集群每天都會定時往ZooKeeper 上創建一個臨時節點,例如/master_election/2020-11-11/binding。在這個過程中,只有一個客戶端能夠成功創建這個節點,那么這個客戶端所在的機器就成為了Master。同時,其他沒有在ZooKeeper上成功創建節點的客戶端,都會在節點/master_election/2020-11-11 上注冊一個子節點變更的 Watcher,用于監控當前的 Master 機器是否存活,一旦發現當前的 Master 掛了,那么其余的客戶端將會重新進行Master選舉。
從上面的講解中,我們可以看到,如果僅僅只是想實現Master選舉的話,那么其實只需要有一個能夠保證數據唯一性的組件即可,例如關系型數據庫的主鍵模型就是非常不錯的選擇。但是,如果希望能夠快速地進行集群
Master 動態選舉,那么就可以基于 ZooKeeper來實現。
猜你喜歡: