Giraph原始碼分析(四)—— Master 如何檢查Worker啟動

wangsys發表於2021-09-09

本文的目的

說明Giraph如何藉助ZooKeeper來實現Master與Workers間的同步(不太確定)。

環境

在單機上(機器名:giraphx)啟動了2個workers。

Giraph遵從單Master多Workers結構,BSPServiceMaster使用MasterThread執行緒來進行全域性的同步。每個Worker啟動成功後,會向Master彙報自身的健康狀況,那麼Master是如何檢測Workers是否都成功啟動了?

Master在ZooKeeper上創兩個目錄,_workerHealthyDir和 _workerUnhealthyDir,分別用來記錄Healthy Workers和UnHealthy Workers。

主要在BspServiceMaster類中的getAllWorkerInfos()方法來完成,其呼叫關係如下,注意下getAllWorkerInfos()到MasterThread.run()方法呼叫關係,比較難找。

圖片描述

建立的兩個目錄如下:

/_hadoopBsp/job_201404102333_0002/_applicationAttemptsDir/0/_superstepDir/-1/_workerHealthyDir /_hadoopBsp/job_201404102333_0002/_applicationAttemptsDir/0/_superstepDir/-1/_workerUnhealthyDir

每個Worker在setup()中,呼叫registerHealth()方法來註冊自身的狀態。

若自身是Healthy的,則在_workerHealthyDir目錄下新增子節點 /wokerInfo.getHostNameId(),否則在_workerUnhealthyDir目錄下新增。wokerInfo.getHostNameId()為:Hostname+“_”+TaskId。 Task1和Task2 (Task 0是master) 建立的子節點如下:

/_hadoopBsp/job_201404102333_0002/_applicationAttemptsDir/0/_superstepDir/-1/_workerHealthyDir/giraphx_1
/_hadoopBsp/job_201404102333_0002/_applicationAttemptsDir/0/_superstepDir/-1/_workerHealthyDir/giraphx_2

Master 在checkWorkers()方法中,在While死迴圈中(實際有超時限制),透過呼叫getAllWorkerInfos()方法來獲取_workerHealthyDir目錄下的子節點,然後比較子節點數目是否達到maxWorkers(啟動job時定義的,-w引數)。

若小於maxWorkers,則繼續呼叫getAllWorkerInfos()方法進行下一輪檢測;若等於maxWorker,退出While迴圈,然後返回healthyWorkersInfoList:[Worker(hostname=giraphx, MRtaskID=1, port=30001), Worker(hostname=giraphx, MRtaskID=2, port=30002)] 。

**問題:**由於在分散式環境中,每個Worker和Maste都是並行執行,彼此不知道對方的執行情況。上述第3步驟中,若還有子節點還沒有建立,就一直在while死迴圈中呼叫來檢測getAllWorkerInfos()方法檢測,效率比較低下,當然也比較笨!

Giraph借用ZooKeeper來高效的進行檢測。設計理念如下:

  1. master在獲取子節點時,註冊Watcher(為註冊器,用於觸發相應事件)。

圖片描述

若某個task建立了子節點後,就會觸發Watcher事件。

若子節點數目小於maxWorkers,就呼叫 workerHealthRegistrationChanged的await()方法釋放當前執行緒的鎖,陷入等待狀態。不會進行無用的檢測。

說明:workerHealthRegistrationChanged為PredicateLock型別(implements BspEvent介面),PredicateLock裡面使用可重入鎖 ReentrantLock和Condition進行執行緒的控制。

當某個task建立了子節點後,觸發Watcher事件。

呼叫BspService中的public final void Process(WatchedEvent event)事件,該方法根據事件的路徑來啟用相應的BspEvent事件。此處對應的是:

圖片描述

實驗執行如下:

s(926)) - process: Got a new event, path = /_hadoopBsp/job_201404102333_0002/_applicationAttemptsDir/0/_superstepDir/-1/_workerHealthyDir, type = NodeChildrenChanged, state = SyncConnected INFO bsp.BspService (BspService.java:process(960)) - process: workerHealthRegistrationChanged (worker health reported - healthy/unhealthy )

這樣就會啟用master執行緒,開始下一輪檢測。

子節點數目等於maxWorkers時,就停止。

總結:每建立一個子節點時,才會進行一次檢測,效率較高!

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3244/viewspace-2823533/,如需轉載,請註明出處,否則將追究法律責任。

相關文章