前言:
在有些情況下,運行於Hadoop集群上的一些mapreduce作業本身的數據量並不是很大,如果此時的任務分片很多,那么為每個map任務或者reduce任務頻繁創建Container,勢必會增加Hadoop集群的資源消耗,並且因為創建分配Container本身的開銷,還會增加這些任務的運行時延。如果能將這些小任務都放入少量的Container中執行,將會解決這些問題。好在Hadoop本身已經提供了這種功能,只需要我們理解其原理,並應用它。
Uber運行模式就是解決此類問題的現成解決方案。
uber運行模式:
Uber運行模式對小作業進行優化,不會給每個任務分別申請分配Container資源,這些小任務將統一在一個Container中按照先執行map任務后執行reduce任務的順序串行執行。那么什么樣的任務,mapreduce框架會認為它是小任務呢?
- map任務的數量不大於mapreduce.job.ubertask.maxmaps參數(默認值是9)的值;
- reduce任務的數量不大於mapreduce.job.ubertask.maxreduces參數(默認值是1)的值;
- 輸入文件大小不大於mapreduce.job.ubertask.maxbytes參數(默認為1個Block的字節大小)的值;
- map任務和reduce任務需要的資源量不能大於MRAppMaster(mapreduce作業的ApplicationMaster)可用的資源總量;也就是說yarn.app.mapreduce.am.resource.mb必須大於mapreduce.map.memory.mb和mapreduce.reduce.memory.mb以及yarn.app .mapreduce.am.resource.cpu-vcores必須大於mapreduce.map.cpu.vcores和mapreduce.reduce.cpu.vcores以啟用ubertask。
參數mapreduce.job.ubertask.enable用來控制是否開啟Uber運行模式,默認為false。
優化:該優化在單個JVM中按順序運行“足夠小”的作業。
以WordCount例
(1)限制任務的划分數量:
hadoop自帶的Wordcount程序里面,MapReduce數量已經通過Job.setNumReduceTasks(int)方法已經設置為1,因此滿足mapreduce.job.ubertask.maxreduces參數的限制。所以我們首先控制下map任務的數量,我們通過設置mapreduce.input.fileinputformat.split.maxsize參數來限制。看看在滿足小任務前提,但是不開啟Uber運行模式時的執行情況。執行命令如下:
[hadoop@master hadoop-2.9.0]$ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.9.0.jar wordcount -D mapreduce.input.fileinputformat.split.maxsize=6 /wc.input /wc.output_2
file wc.intput為25K 參數 mapreduce.input.fileinputformat.split.maxsize=6 是以k為單位,我這里在分片的時候指定的6K,所以,最終分的片為5個,從下圖可以明顯的看出來,處理的總文件為1,分片數量為5,uber模式為false;還可以看到一共6個map任務,一個reduce任務。
結果如下:
web界面查看:
(2)開啟uber模式
[hadoop@master hadoop-2.9.0]$ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.9.0.jar wordcount -D mapreduce.input.fileinputformat.split.maxsize=6 -D mapreduce.job.ubertask.enable=true /wc.input /wc.output_5
wc.input 35k
結果如下:
這里是是6個map任務和1個reduce任務,但是之前的數據本地map任務= 5一行信息已經變為當地的其他maptasks=6。此外還增加了TOTAL_LAUNCHED_UBERTASKS、NUM_UBER_SUBMAPS、NUM_UBER_SUBREDUCES等信息,如下圖所示:
以下列出這幾個信息的含義:
輸出字段 | 描述 |
TOTAL_LAUNCHED_UBERTASKS | 啟動的Uber任務數 |
NUM_UBER_SUBMAPS | Uber任務中的map任務數 |
NUM_UBER_SUBREDUCES | Uber中reduce任務數 |
其他測試
由於我主動控制了分片大小,導致分片數量是6,這小於mapreduce.job.ubertask.maxmaps參數的默認值9。按照之前的介紹,當map任務數量大於9時,那么這個作業就不會被認為小任務。所以我們先將分片大小調整為20字節,使得map任務的數量剛好等於9,然后執行以下命令:
[hadoop@master hadoop-2.9.0]hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.9.0.jar wordcount -D mapreduce.input.fileinputformat.split.maxsize=20 -D mapreduce.job.ubertask.enable=true /wc.input /wc.output_6
file:wc.input 為172k
我們看到的確將輸入數據划分為9份了其它信息如下
[hadoop@master hadoop-2.9.0]hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.9.0.jar wordcount -D mapreduce.input.fileinputformat.split.maxsize=19 -D mapreduce.job.ubertask.enable=true /wc.input /wc.output_7
我們看到的確將輸入數據划分為10份了其它信息如下:
- 設置當map任務全部運行結束后才開始reduce任務(參數mapreduce.job.reduce.slowstart.completedmaps設置為1.0,默認0.05)。
- 將當前Job的最大map任務嘗試執行次數(參數mapreduce.map.maxattempts)和最大reduce任務嘗試次數(參數mapreduce.reduce.maxattempts)都設置為1,默認為4。
- 取消當前Job的map任務的推斷執行(參數mapreduce.map.speculative設置為false)和reduce任務的推斷執行(參數mapreduce.reduce.speculative設置為false),默認為。