Tachyon框架的Worker心跳及Master高可用性分析

0 概述

    分佈式框架中的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 HA

    Master節點在初始化的時候會創建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方法。

-------------------------------------------------------------------------------

如果您看了本篇博客,覺得對您有所收穫,請點擊下方的 [頂]

如果您想轉載本博客,請註明出處

如果您對本文有意見或者建議,歡迎留言

感謝您的閱讀,請關注我的後續博客


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章