MapReduce的容錯機制

Failures

在現實世界中,難免遇到用戶代碼錯誤、進程崩潰、機器宕機等情況。使用Hadoop的一個好處是它有能力處理這些失敗,使你的job能夠成功完成。我們需要考慮以下實體的失敗:task、application master、node manager 、resource manager。

Task Failure

考慮第一種情況task失敗。最常見的task 失敗是在map或reduce task中的用戶代碼拋出一個運行時異常。如果發生這種情況,JVM在退出之前將向父application master報告一個錯誤,錯誤最終會被寫進用戶的日誌中。application master將task標記爲失敗,並且釋放container,以便其資源可用於其它的task。

對於Streaming task,如果Streaming Process以非零代碼退出(即非正常退出),它將被標記爲失敗。這種行爲有stream.non.zero.exit.is.failure屬性控制(默認爲true)。

另一種失敗的情況是JVM突然退出——也許有一個JVM bug導致JVM的退出。在這種情況下,node manager通知application master task進程已經退出,然後application master嘗試標記task爲失敗狀態。

對掛起task的處理有些不同,如果application master 感知到它已有一段時間沒有接收到進度更新的通知,它會將task標記爲failed,並且在一段時間後會自動殺掉JVM進程。任務視爲失敗的超時時間通常爲10分鐘,也可以通過設置mapreduce.task.timeout屬性值(單位爲毫秒)針對每個job進行配置。

設置mapreduce.task.timeout的屬性值爲0將禁用超時失敗的約束,對於長時間運行的task來說,將永遠不會被標記爲failed,掛起的task將永遠不會釋放container,並且,隨着時間的推移可能會導致集羣變慢。這種情況是應該要避免的,並且確保任務定期報告進度就可以了。

當application master被告知一個task已經失敗,那麼它會重新調度執行task。application mastet會盡量避免在之前失敗的同一個節點上重新調度task。此外,如果一個task失敗4次,將不會被再次重試。這個次數是可以配置的。運行job的最大嘗試次數是由map task的mapreduce.map.maxattempts屬性和reduce task的mapreduce.reduce.maxattempts屬性值控制的。默認,任何一個task失敗了4次(或是配置的最大嘗試次數),那麼整個job都將是失敗的。

對於一些應用,如果僅有少數的task失敗,並不希望終止job,因爲儘管有些失敗,但是結果也許還是可以用的。在這種情況下,可以爲job設置允許task失敗而不會觸發job失敗的最大百分比。Map task和Reduce task是使用mapreduce.map.failures.maxpercent 和mapreduce.reduce.failures.maxpercent屬性來單獨控制的。

一個task被殺死,和它失敗是不同的。一個task被殺死可能是因爲它投機性的重複,或是node manager運行故障、或是application master要殺死所有運行在其上的task。被殺死的task不會再被嘗試重新調度,因爲這不是task的錯誤,而是被殺死的。

用戶也可以通過Web UI或命令行來殺死或失敗task,同樣,Job也是可以被殺死的。

Application Master Failure

就像MapReduce的task,對於失敗的task會嘗試幾次重新調度,同樣在YARN中的應用如果失敗了也會重新嘗試運行。嘗試運行MapReduce application master的最大次數是由mapreduce.am.max-attempts屬性控制的,默認值爲2。所以如果一個MapReduce application master失敗了兩次,那麼它將不會被再次嘗試,MapReduce Job將失敗。

YARN規定了MapReduce application master在集羣中的最大嘗試次數,獨立的應用不能超過這個限制。這個限制通過yarn.resourcemanager.am.max-attempts屬性設置,默認爲2,所以,如果你想增加MapReduce application master的嘗試次數,還必須要在集羣中增加YARN的設置。

恢復方式如下:application master 定期發送心跳到resource manager,包括application master失敗的事件,如果resource manager 檢測到失敗的事件,會在一個新的container重新啓動一個application master的實例(由node manager管理)。對於新的MapReduce application master來說,它會根據已失敗的application運行的job的歷史記錄來恢復task的狀態,所以不需要重新運行它們。恢復默認是啓用的,但可以通過設置yarn.app.mapreduce.am.job.recovery.enable屬性值爲false禁用它。

MapReduce客戶端會向application master輪詢進度報告,但是如果application master失敗了,客戶端需要重新查找一個新的實例。在job初始化期間,客戶端會向resource manager詢問application master的地址,然後緩存它,所以它每次輪詢application master的請求不會使resource manager超載。但是,如果application master失敗了,客戶端的輪詢請求將會超時,此時客戶端會向resource manager請求一個新的application master的地址。這個過程對用戶是透明的。

Node Manager Failure

如果一個node manage節點因中斷或運行緩慢而失敗,那麼它將不會發送心跳到resource manager(或者發送次數較少)。如果resource manage在10分鐘內(這個配置可以通過yarn.resourcemanager.nm.liveness-monitor.expiry-interval-ms屬性設置,以毫秒爲單位)沒有接收到一個心跳,它會感知到node manager已經停了,並把它衝節點集羣中移除。

在出現故障的node manager節點上運行的任何task或application master將會按上兩節描述的機制來恢復。另外,對於出現故障的node manager節點,application master分配在其上已經成功運行完成的map task,如果這些map task屬於未完成的Job,它們將會被重新運行,因爲它們的中間輸出存放在故障node manager節點的本地文件系統中,reduce task可能不能訪問。

對於一個應用來說,如果node manage出現故障的機率比較高,它可能會被列入黑名單(blacklisted),即使node manager自身沒有出現故障。黑名單是由application master管理的,如果一個node manager有3個以上的task失敗,application master將會在其它的節點上重新調度這些task。用戶可以使用job的mapreduce.job.maxtaskfailures.per.tracker屬性設置一個閾值。

需要注意的是:resource manager 並不管理黑名單,所以,對於新的job的task,在一個即使被之前job正在運行的application master加入黑名單的node manager節點上也是可以被調度。

Resource Manager Failure

Resource manager出現故障是比較嚴重的,因爲沒有它,job 和 task都不能被啓動。默認配置,resource manager是一個單點故障,因爲在機器出現故障時,所有的job都會失敗,並且不能被恢復。

爲了實現高可用(HA),有必要以一種active-standby(活動-備用)配置模式運行一對resource manager。如果活動的resource manager出現故障,備用的resource manager可以很開的接管,並且對客戶端來說沒有明顯的中斷現象。

有關所有運行的應用信息都會被存儲在一個具有高可用的狀態存儲中(比如Zookeeper或HDFS),所以,備用的resource manager可以恢復到出現故障的活動的resource manager的核心狀態。node manager的信息並沒有存儲在狀態存儲中,因爲在node manager向新的resource manager 發送第一個心跳時,它可以從新的resource manager中快速重建。(要注意的是task不是resource manager狀態的一部分,因爲task是由application master管理的。因此,和MapReduce 1中的jobtracker相比,要更容易管理)。

當新的resource manager啓動,它從狀態存儲中讀取應用信息,然後爲集羣中正在運行的所有應用重啓application master。這不會被計入失敗應用的嘗試次數(即不計入yarn.resourcemanager.am.max-attempts),因爲application並沒有因錯誤的代碼而失敗,而是被系統強制殺死的。實際上,application master的重啓並不影響MapReduce application,因爲它們會通過已完成的task來恢復工作。

resource manager從standby轉爲active,是由故障控制器處理的。故障控制器默認是自動的,它使用ZooKeeper的選舉領導者的方式,確保在同一時間只有一個active resource manager。

不像HDFS的高可用(見http://blog.csdn.net/qiruiduni/article/details/48010745這篇文章的“HDFS High Availability”部分),故障控制器不必是一個獨立的進程,而是默認嵌入到resource manager中的,當然也是可以手動配置的,但不推薦這樣做。

客戶端和node manager必須被配置來處理resource manager的故障切換,因爲存在兩種可能與resource manager通信。它們會以循環的方式嘗試連接每一個resource manager,直到找到一個active manager。如果active resource manager出現故障,它們將重試直到standby resource manager變爲active resource manager。





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