MapReduce如何作為Yarn應用程式執行?
本文作為《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頁面:
https://github.com/ 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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MapReduce程式執行流程
- Wpf應用程式作為一個單獨的可執行檔案
- hadoop_MapReduce yarnHadoopYarn
- MapReduce執行流程
- Yarn執行原理Yarn
- 在Docker容器中使用Hadoop執行Python MapReduce作業DockerHadoopPython
- HttpRuntime應用程式的執行時HTTP
- 使用MapReduce執行WordCount案例
- MapReduce的執行流程概述
- standalone執行模式下 應用模式作業部署模式
- Hadoop學習(二)——MapReduce\Yarn架構HadoopYarn架構
- hadoop的mapreduce串聯執行Hadoop
- MapReduce 執行全過程解析
- yarn應用程式安裝後,報錯檢查Yarn
- DMAIC如何作為解決問題的方法執行?AI
- 如何讓Mac的Dock僅顯示正在執行的應用程式?Mac
- 大資料系列4:Yarn以及MapReduce 2大資料Yarn
- Docker容器中執行.Net Core應用程式Docker
- 在 WASI 上執行 .NET 7 應用程式
- 為什麼Python停止執行?該如何應對?Python
- 如何用一套程式碼執行跨多作業系統應用作業系統
- 編寫執行緒安全的JSP應用程式執行緒JS
- Netweaver和CloudFoundry是如何執行Web應用的?CloudWeb
- 多執行緒應用執行緒
- 基於SkyEye執行Android——應用最為廣泛的移動裝置作業系統Android作業系統
- Redis In Action 筆記(六):使用 Redis 作為應用程式元件Redis筆記元件
- Python開發Windows桌面應用程式(三)應用程式打包成exeWindows可執行檔案PythonWindows
- PyQt應用程式中的多執行緒:使用Qt還是Python執行緒?QT執行緒Python
- [譯] 將 React 作為 UI 執行時ReactUI
- Nodejs 揭秘:單執行緒魔法背後的真相以及它如何為高效能應用程式提供動力NodeJS執行緒
- 初識MapReduce的應用場景(附JAVA和Python程式碼)JavaPython
- 如何用WebIDE開啟並執行CRM Fiori應用WebIDE
- 安卓教育應用如何在linux上流暢執行安卓Linux
- TensorFlow2020:如何使用Tensorflow.js執行計算機視覺應用程式?JS計算機視覺
- 【作業系統】程式與執行緒作業系統執行緒
- Hadoop框架:Yarn基本結構和執行原理Hadoop框架Yarn
- 用 Git 作為聊天應用的後端Git後端
- nuxt作為主應用接入qiankun的實踐(附程式碼)UX