分布式框架中的Master-Slave類型,Slave節點負責工作的具體執行,Master負責任務的分發或者相關元數據的存儲等。一般情況下,一個Master節點都會對應多個Slave節點,Master在分配任務時需要知道當前有哪些Slave節點是可以接受自己所發的命令的(Slave節點有可能因為各種原因掛掉),因此需要在其內部維持一個鏈表來保存所有還活著的Slave節點。HBase的HMaster是這樣、HDFS的NameNode是這樣、Tachyon的Master節點也是這樣。Slave節點通過不斷的心跳匯報(HeartBeat)來和Master通信,Master把收到心跳匯報的Slave節點看做是目前存活的,否則就說明Slave節點掛掉了。除了維持存活性以外,Master節點通常還會把需要執行的命令通過心跳返回給Slave節點,Slave節點接收到后執行Master發來的命令,完成一次交互。
Master是核心,它要是掛掉了對整個系統都是致命的影響,單點問題是每個分布式框架都要考慮的問題。應用和實現了Paxos算法的Zookeeper,是解決一致性問題的利器。HDFS、Storm、HBase等都采用Zookeeper作為元數據信息HA的載體,Tachyon也不例外。
1 Worker心跳1.1 總體流程Tachyon的Worker節點,通過不斷心跳向Master匯報當前Worker中已使用的內存大小和準備刪除的數據塊信息,Master接受心跳匯報后返回給Worker節點相關的執行命令,這些命令可以是Register、Free等,也可以是Nothing。

其中,需要說明的地方如下:
(1)Worker心跳的時間間隔默認為1秒,由參數tachyon.worker.to.master.heartbeat.interval.ms設定。
(2)Worker心跳的超時時間默認為10秒,由參數tachyon.worker.heartbeat.timeout.ms設定。
(3)Master返回給Worker的命令主要有五種,分別是:Unknown、Nothing、Register、Free、Delete。Nothing命令什么都不做;Register命令執行Worker向Master的注冊,Master會返回WorkerId存儲在Worker本地;Free命令要釋放Worker內存中存儲的數據;Delete命令則既要刪除內存中的數據也要刪除磁盤上的數據。
(4)心跳的具體執行是調用的WorkerStorage的heartbeat方法。
(5)CheckStatus則會檢查當前Worker節點所管理的內存使用情況。
1.2 HeartBeat正常處理
其中,需要說明的地方如下:
(1)首先獲取所有需要從當前Worker節點的內存中移除的Block的信息,Block被移除一般有如下幾種情況,當Master發來Free命令時、WorkerStorage初始化時、內存不夠時需要使用LRU算法換入換出。
(2) 調用MasterClient的worker_heartbeat方法進行心跳匯報給Master,此處的MasterClient會通過MasterService.Client對象調用Master的Thrift服務進行消息傳遞,類似于HDFS中的RPC通信的動態代理。
(3)連接建立是調用的MasterClient類的connect方法,其主要目的是為了創建MasterService.client對象,即Thrift服務的客戶端。步驟如下:
Step1:調用cleanConnect方法,主要是關閉thrift的transport端口、并且將當前的HeartbeatThread線程停止掉如果其對象不為null的話,則將mIsShutdown設置為true,并且會拋出TException。首次進行clean的話,幾乎沒有什么要做的事情。
Step2:clean之后,進入while循環,準備獲取master地址進行建立連接,while循環的條件為tries ++ < MAX_CONNECT_TRY && !mIsShutdown,默認重試5次。
Step3:獲取Master的當前地址,使用getMasterAddress方法,在ZK中查找leader目錄下的所有節點,根據節點的創建時間,找到最新的那個節點作為當前需要連接的Active Master節點。
Step4:初始化Thrift客戶端和服務端通信的協議,此處為TBinaryPRotocol。
Step5:初始化Thrift客戶端MasterService.Client對象。
Step6:打開協議的Transport,就是數據傳輸通道,準備進行讀寫,如果打開失敗,則會拋出TTransportException,接著停止用于維持連接的心跳線程HeartbeatThread,并且sleep1秒鐘后進入while的失敗重試,達到失敗次數上限,拋出TException。
Step7:初始化一個心跳線程HeartbeatThread,不斷的和服務端進行心跳,超時時間為tachyon.user.master.client.timeout.ms配置的屬性值,默認10秒,用于保持上面已建立的Thrift連接的存活,如果期間心跳超時,會觸發調用cleanConnect方法,此時就會關閉Thrift數據傳輸通道,終止此維持連接心跳線程。
(4) connect連接成功后,會調用MasterService.client的worker_heartbeat方法進行心跳處理,結果返回的是Command。其中worker_heartbeat的處理步驟如下:
Step1:首先調用send_worker_heartbeat方法,主要是設置workerId、已使用的內存大小、worker已刪除的blockId。
Step2:創建一個worker_heartbeat_result對象,worker_heartbeat_result是MasterService中的靜態內部類,這里面會定義兩種Field,SUCCESS_FIELD_DESC值為0,E_FIELD_DESC為1。
Step3:通過Thrift服務發送給Master端,由MasterInfo的workerHeartbeat方法負責處理。如果Master節點找不到心跳匯報的Worker信息,則返回給Worker節點CommandType.Register命令。如果有需要釋放的內存,則Master返回給Worker節點CommandType.Free命令。否則返回給CommandType.Nothing命令給Worker節點。
1.3 HeartBeat異常處理在TachyonWorker心跳匯報過程中,可能會出現兩種主要的異常:BlockInfoException和TException異常。
(1)如果出現BlockInfoException,則在TachyonWorker中調用WorkerStorage.checkStatus()方法,如果此時繼續心跳的條件仍然成立,即mStop為false,則繼續循環進行心跳匯報。
(2)如果出現TException,則在TachyonWorker中調用WorkerStorage的resetMasterClient方法進行重置MasterClient對象,利用connect方法連接Thrift服務端。需要注意的是,Worker心跳超時判斷,默認超時時間為10秒,如果超時,則拋出RuntimeException,心跳線程直接就掛掉了;如果沒有心跳超時,則繼續進行WorkerStorage的checkStatus,重新檢查心跳條件,進入下次心跳。
2 Master HAMaster節點在初始化的時候會創建Journal目錄,如果底層文件系統是HDFS的話,那就直接在HDFS上創建對應的目錄,并且需要格式化(這里的格式化實際上是創建一個空的文件用于標注Format完畢)。
Tachyon的文件系統信息依靠Edits日志 + Fsimage鏡像保存(分別是image.data文件和log.data文件),Edits日志是Tachyon文件系統的元數據信息的增量Log,Fsimage是在某個時刻的快照。Tachyon Master在啟動時會首先從Fsimage文件中讀取文件系統元數據信息,即各種數據節點(文件、目錄、Raw表、Checkpoint、依賴關系等)信息,然后再從繼續Edits(可能多個)中讀取增量操作記錄,Edits日志的內容基本對應于Tachyon文件系統Client的一些相關操作,包括文件的添加,刪除,重命名,數據塊的添加等。但是這里的Edits日志不包括實際的文件內容數據,只是元數據信息,當Cache中的文件內容丟失,而又沒有持久化,也沒有綁定相關lineage信息時,對應的文件的內容就會丟失。搞定完這些,Tachyon Master會先把當前的元數據信息寫出為新的Fsimage。
采用Zookeeper作為Master的HA實現機制的時候,處于Standby角色的Master會定期將Editlog合并,并創建Standby的Fsimage,如果沒有Standby的Master則只有在啟動過程中,才會通過合并EditsLog產生新的Fsimage。
Master的Active選舉,通過LeaderSelectorClient類來完成,如果當前Master被選舉為Leader,則停止EditsLog的滾動,調用MasterInfo的init方法進行初始化相關參數,進而啟動Web的服務UIWebServer(Standby狀態的Master沒有WebUI服務),接著初始化Master的服務處理對象MasterServiceHandler并啟動Thrift服務。
需要注意的是:
(1) JOURNAL的路徑、格式化文件前綴、service和web的ip及端口的設定都是在MasterConf類中設置的;
(2) MasterInfo的init方法會依次做如下事情:
Step1:加載EditsLog文件到內存
Step2:創建新的鏡像文件
Step3:創建新的EditsLog日志文件
Step4: 創建心跳匯報器MasterInfoHeartbeatExecutor并啟動
Step5: 創建文件丟失恢復器RecomputationScheduler并啟動
(3)Master也有心跳,只不過是做周期性的系統狀態檢查
Step1:獲取超時的worker列表BlockingQueue,從Master端的Worker存儲列表中刪除
Step2:嘗試從超時worker列表中恢復丟失的文件
Step3:重啟所有超時的worker列表,這一點很重要!
(4)Master在Zookeeper中會創建兩個節點,分別是election節點,在其下面子節點是CreateMode.EPHEMERAL_SEQUENTIAL類型的,即臨時節點;leader節點,在其下的子節點是CreateMode.PERSISTENT類型的,用于維護當前存活的Master節點信息。
(5) 由于當前Active Master可能是變化的,所以Worker進行選擇Master進行通信的時候,需要首先從Zookeeper中的leader目錄下取出所有的Master節點進行遍歷,如果只有一個Master,則直接返回,否則,查找出cTime最大的那個Master作為當前的Active節點,由Worker節點負責和它通信。而Worker端在進行心跳匯報的時候,會重試五次,仍然失敗則拋出異常TException,由TachyonWorker的run方法catch,調用resetMasterClient方法進行重新設置,每次connect的時候都會從Zookeeper中獲取最新的Active Master地址,如果一段時間后仍然連接不上master,則停止心跳,通過調用cleanConnect方法。
-------------------------------------------------------------------------------
如果您看了本篇博客,覺得對您有所收獲,請點擊右下角的[推薦]
如果您想轉載本博客,請注明出處
如果您對本文有意見或者建議,歡迎留言
感謝您的閱讀,請關注我的后續博客
新聞熱點
疑難解答