MapReduce如何作為Yarn應用程式執行?

趙鈺瑩發表於2018-09-06

本文作為《Hadoop從入門到精通》第二章的第二節,主要介紹Yarn出現之後,MapReduce體系架構發生的改變、其在Hadoop叢集中的執行原理以及讓MapReduce作為Yarn之上的應用程式正常執行並保持向後相容性等內容。

我們必須承認,從Hadoop 1.x過渡到Hadoop 2.x經歷了巨大的改變,MapReduce便是改變的一部分。在Hadoop 1.x中,MapReduce是本地資料處理的唯一方法。當時,業界普遍總結出的一條結論是:MapReduce只能支援4000節點左右的主機。這是因為MapReduce的核心是JobTracker,所有任務資訊都彙總到Job Tracker,存在單點故障不說,任務過多會造成極大的記憶體開銷,失敗風險也陡然增加。

從操作角度來看,當時的MapReduce有任何修復或更新都會強制進行系統級別的升級更新,強制讓分散式叢集系統的每一個使用者端同時更新,而這個過程使用者本身可能並不認可,但不得不浪費時間適應新的版本,這樣的使用者體驗是極其糟糕的。

Yarn的出現是為了讓Hadoop叢集可以執行任何型別的作業,並且唯一要求是應用程式遵循Yarn規範,這意味著MapReduce必須成為Yarn應用程式,並要求Hadoop開發人員重寫MapReduce的關鍵部分。

2.2.1 解析Yarn MapReduce應用程式

我們可以將Yarn理解為叢集中的分散式作業系統,而MapReduce便是其上的一個應用程式,我們必須對MapReduce架構進行更改以移植到Yarn。

圖2.10 MapReduce2 Yarn應用程式互動

每個MapReduce任務都可作為單獨的Yarn應用程式執行,當啟動新的MapReduce任務時,首先,客戶端會計算輸入分片並將其與剩下的任務資源一起寫入HDFS。其次,客戶端與ResourceManager通訊以為MapReduce任務建立ApplicationMaster。ApplicationMaster實際上是一個容器,因此當該資源在叢集上可用時,ResourceManager將與NodeManager通訊以建立ApplicationMaster容器。然後,MapReduce ApplicationMaster(MRAM)負責排程和協調資源並監控容器狀態。MRAM從HDFS中提取輸入資訊,以便與ResourceManager通訊時,可以請求在其輸入資料本地節點上啟動map容器。對ResourceManager的容器分配請求依賴於在ApplicationMaster和ResourceManager之間傳遞的心跳訊息,心跳可能包含為應用程式分配容器等詳細資訊,這部分不需要過分關心,Yarn可以幫我們實現。

資料區域性性作為體系結構的重要組成部分——當它請求map容器時,MapReduce ApplicationManager將使用輸入分片的詳細資訊將容器分配給包含輸入分片的節點,ResourceManager也將在這些輸入分片節點進行容器分配的最佳嘗試。MapReduce ApplicationManager一旦被分配容器,就會與NodeManager通訊以啟動map或reduce任務。此時,map/reduce程式的行為與在MRv1中的工作方式非常相似。

Shuffle

MapReduce中的shuffle負責對對映器輸出排序並分配到相應的reducers,MapReduce 2並沒有從根本上改變這一做法,主要區別在於map輸出透過ShuffleHandlers獲取,ShuffleHandlers輔助Yarn服務在每個從節點上執行。對shuffle進行了一些次要記憶體管理調整,例如,不再使用io.sort.record.percent。

JobTracker怎麼辦?

你可能會注意到此架構中不再存在JobTracker,但其在此前的版本中作用重大。事實上,JobTracker的排程部分作為通用資源排程程式移動到Yarn ResourceManager中。JobTracker的剩餘部分主要是關於執行和已完成作業的後設資料兩個部分,每個MapReduce ApplicationMaster都託管一個UI,用於呈現當前作業的詳細資訊,一旦作業完成,其詳細資訊將被推送到JobHistoryServer,後者聚合並呈現所有已完成作業的詳細資訊。

2.2.2 配置MapReduce 2到Yarn的埠

本小節,我們將介紹一些受影響的常用屬性以及MapReduce 2中的新屬性。(具體棄用屬性可在官網自行搜尋,此處不一一列舉)

棄用屬性

大多數MapReduce 1(和許多HDFS)屬性都被棄用,而不是簡單的更改了屬性名稱,因此在Hadoop 3.x以上版本中執行時,更新屬性列表是必須的。幸運的是,當執行MapReduce作業時,我們可以在標準輸出上獲得所有已棄用配置屬性的轉儲,其示例如下:

2.2.3 向後相容性

MapReduce的屬性明顯發生了很大改變,因此很多人會擔心其向後相容性是否受到影響。對於具有大量使用者群的系統,向後相容性是一個重要的考慮因素,因為它可以確保快速升級到新版本,而使用者幾乎是無感知的。

指令碼相容性

與Hadoop捆綁在一起的指令碼保持不變,這意味著可以繼續使用hadoop jar ...來啟動作業,並且主要的Hadoop指令碼依舊可用,與Hadoop捆綁的其他指令碼也一樣。

配置

隨著Yarn的引入以及MapReduce成為一個應用程式,MapReduce 2不推薦使用MapReduce 1的屬性名稱,有些不再有效。將MapReduce移植到Yarn時,開發人員盡最大努力保持了現有MapReduce應用程式的向後相容性。它們能夠實現程式碼相容性,但在某些情況下無法保持二進位制相容性:

  • 程式碼相容性意味著只要重新編譯程式碼,現在存在的所有MapReduce程式都可在Yarn上正常執行。這意味著無需複雜修改,程式碼即可在Yarn上執行。

  • 二進位制相容性意味著MapReduce位元組碼將在Yarn上保持不變。換句話說,不必重新編譯程式碼也可與Hadoop 1執行相同的類和JAR,它們在Yarn上也可以正常工作。

“舊”MapReduce API(org.apache.hadoop.mapreduce包)程式碼是二進位制相容的,因此,如果現有MapReduce程式碼僅使用舊的API,那麼只需設定而不需重新編譯程式碼。對於“新”MapReduce API(org.apache.hadoop.mapreduce)的某些用法,則要考慮正在使用的API是否已更改,即類被更改為介面,如下:

  • JobContext

  • TaskAttemptContext

  • Counter

如果正在使用新的MapReduce API並且需要在兩個版本的Hadoop上執行程式碼,那麼這就引出了一個問題。如果正在使用“新”MapReduce API並擁有自己的Input/OutputFormat類或使用計數器,那麼可能需要重新編譯JAR才能與MapReduce 2一起使用。如果必須同時支援MapReduce 1和2,可以建立兩套針對每個版本的MapReduce的JAR,最終你會得到一個十分複雜的系統。

問題:正在使用與MapReduce 2不是二進位制相容的MapReduce程式碼,並且希望能夠以與MapReduce兩個版本相容的方式更新程式碼,應該如何做呢?

解決方案:使用可解決API差異的Hadoop相容庫。Elephant Bird專案包含一個HadoopCompat類,可動態確定正在執行的Hadoop版本,並使用Java反射來呼叫適當的方法以使用Hadoop版本。以下程式碼是用法示例,在InputFormat實現中,TaskAttemptContext從類更改為介面,並且HadoopCompat類用於提取Configuration物件:

import com.alexholmes.hadooputils.util.HadoopCompat; 
import org.apache.hadoop.mapreduce.InputSplit; 
import org.apache.hadoop.mapreduce.RecordReader;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
public class MyInputFormat implements InputFormat 
{ 
@Override
 public RecordReader createRecordReader(InputSplit split, 
                                              TaskAttemptContext context) 
throws IOException { 
final Configuration conf = HadoopCompat.getConfiguration(context); 
     ... 
     }
 }

表2.5 MapReduce新舊版本非二進位制相容的公共類和方法

HadoopCompat類還有一個名為isVersion2x的方法,如果類確定此執行時針對Hadoop 2.x版本,則會返回一個布林值。這只是一個示例,完整資訊可參閱Github上Elephant Bird專案的HadoopCompat頁面:

kevinweil/elephant-bird/blob/master/hadoop-compat/src/main/java/com/twitter/ elephantbird/util/HadoopCompat.java.  

2.2.4 執行MapReduce 2作業

在Hadoop 2.x及以上版本中執行MapRedcue任務的方式與MapReduce 1中的操作基本相同,只是我們可以使用Yarn相關命令來操作。例如,執行Hadoop示例JAR中捆綁的pi作業方式:

$ yarn jar ${HADOOP_HOME}/share/hadoop/mapreduce/*-examples-*.jar pi 2 10
Estimated value of Pi is 3.1428000

2.2.5 監視正在執行的任務並檢視已歸檔任務

執行MapReduce任務時,監控和除錯非常重要,可以檢視任務狀態並訪問任務日誌。在MapReduce 1中,這些工作全部使用JobTracker UI執行,該UI可用於檢視正在執行或已存檔任務的詳細資訊。正如2.2.1中所強調的,MapReduce 2中不再存在JobTracker;它已被ApplicationMaster中的特定UI替換,JobHistoryServer用於顯示已完成作業。 為了獲取map和reduce任務日誌,UI重定向到NodeManager。確定ResourceManager UI的執行位置可以透過檢查Yarn.resourcemanager.webapp.address或Yarn.resourcemanager.webapp.https .address(如果需要HTTPS訪問)的值來檢索ResourceManager主機和埠。在偽分散式的情況下,http:// localhost:8088(或HTTPS的埠8090)將主機和埠複製到瀏覽器就足以訪問UI,因為不需要URL路徑。

 

圖2.11 Yarn ResourceManager UI,顯示當前正在執行的應用程式


2.2.6 Uber任務

執行小型MapReduce任務時,資源排程等過程所需的時間通常佔整個執行時的很大一部分。在MapReduce 1中,沒有任何關於此的開銷,但MapReduce 2已變得更加智慧,現在可以滿足快速執行輕量級任務的需求。

執行小型MapReduce任務

當處理的資料較少時,我們可以考慮在MapReduce ApplicationMaster中執行,因為刪除了MapReduce需要花費的額外時間,並減少了map和reduce程式。

圖2.12 JobHistory UI,顯示已完成的MapReduce應用程式

如果有一個可在小型資料集上執行的MapReduce任務,並且希望避免建立map和reduce程式的開銷。 那麼,你可以配置以啟用uber任務,這將在與ApplicationMaster相同的程式中執行mapper和Reducer。Uber任務是在MapReduce ApplicationMaster中執行作業,ApplicationMaster不是與ResourceManager聯絡以建立map和reduce容器,而是在其自己的程式中執行map和reduce作業,並避免啟動和與遠端容器通訊的開銷。要啟用uber作業,需要設定以下屬性:

mapreduce.job.ubertask.enable=true

表2.6 列出了一些控制uberization作業質量的附加屬性

執行uber作業時,MapReduce會禁用 (speculative execution ),並將任務的最大嘗試次數設定為1。Uber作業是MapReduce後期新增功能,它們只適用於Yarn。

如今,我們已經看到了Yarn生態系統的快速成長。我們生活在多資料中心執行多個不同系統的世界,所有系統都有其存在的價值,但對系統管理員和架構師帶來了前所未有的挑戰,他們需要支援這些系統並保證它們正常運轉,系統之間的資料交換成本昂貴且異常複雜,每個系統都必須解決相同的分散式問題,例如容錯、分散式儲存、日誌處理以及資源排程。因此,Yarn與其他生態的集合一直是非常有意思的話題,在本章的最後一節,我們將會列舉Yarn與其他生態集合示例。

相關文章:

1、第一章:Hadoop生態系統及執行MapReduce任務介紹!(連結: http://blog.itpub.net/31077337/viewspace-2213549/)

2、學習Hadoop生態第一步:Yarn基本原理和資源排程解析!(連結:http://blog.itpub.net/31077337/viewspace-2213602/)

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

相關文章