MapReduce工作流程(Job與Shuffle)總結

覺得有幫助的,請多多支持博主,點贊關注哦~

MapReduce 工作流程

1、MapReduce作業執行流程

在這裏插入圖片描述

1.1、提交作業

客戶端向ResourceManager提交作業。首先,用戶需要將所有應該配置的參數根據需求配置好。作業提交之後,就會進入自動化執行。在這個過程中,用戶只能監控程序的執行情況和強制中斷作業,但是不能對作業的執行過程進行任何干預。

提交作業的基本過程如下:

  1. 客戶端通過Runjob()方法啓動作業提交。
  2. 客戶端通過ResourceManager的getNewJobId()請求一個新的作業ID。
  3. 客戶端檢查作業的輸出說明,計算作業的輸入分片等,如果有問題,就拋出異常,如果正常,就將運行作業所需的資源(如作業Jar文件,配置文件,計算所得的輸入分片等)複製到一個以作業ID命名的目錄中。
  4. 通過調用ResourceManager的submitApplication()方法告知作業準備執行。

1.2、初始化作業

​ 在ResourceManager端開始初始化工作,包括在其內存裏建立一系列數據結構,來記錄這個Job的運行情況。
​ ResourceManager 接收到對其 submitApplication()方法的調用後,就會把這個調用放入一個內部隊列中,交由作業調度器(scheduler)進行調度。初始化主要是創建一個表示正在運行作業的對象,以便跟蹤任務的狀態和進程。

  1. 調度器(Scheduler)分配一個容器(步驟5.a),然後資源管理器(ResourceManager)在節點管理器(NodeManager)的管理下在容器中啓動應用程序的master進程(步驟5b)
  2. 應用程序管理器MRAppMaster對作業進行初始化:
    通過創建多個簿記對象以保持對作業進度的跟蹤,因爲它將接受來自任務的進度和完成報告。
  3. MRAppMaster接來自共享文件系統的在客戶端計算的輸入分片。
    它對每一個分片創建一個map任務對象以及由mapreduce.job.reduces屬性確定的多個reduce任務對象。
備註:
MRAppMaster決定如何運行構成MapReduce作業的各個任務。如果作業很小:
配置了Yarn的uber mode(可用true):就選擇在與它同一個JVM上運行任務
配置了Yarn的Uber mode(不可用false):

1.2.1、什麼是小任務

【默認情況下】
小任務就是<10個mapper並且只有1個reducer並且輸入大小小於一個HDFS塊的任務。
【如何修改參數】

通過設置mapreduce.job.ubertask.maxmaps(默認值:9)
mapreduce.job.ubertask.maxreduces(默認值:1)
mapreduce.job.ubertask.maxbytes可以改變一個作業的上述值。

將mapreduce.job.ubertask.enable設置爲false也可以完全使uber任務不可用

1.2.2、什麼是Uber模式

uber mode可以理解成]VM重用,是對小作業進行優化,不會給每個任務分別分配Contianer資源,這些小任務將統一在一個container中按照先執行map任務後執行reduce任務的順序串執行。

該模式是Hadoop2.x開始引入的;以Uber模式運行MR作業,所有的Map任務和Reduce任務將會在Application Master所在的容器(container)中運行,也就是說整個MR作業運行的過程只會啓動AM container,因爲不需要啓動mapper containers和reducer containers。

這是一種針對MR小作業的優化機制。即如果作業足夠小,則所有任務在一個JVM中完成要比爲每個任務啓動一個JVM更划算。

1.3、任務分配

注意:執行第8步,是在uber mode爲false時才執行

  1. MRAppMaster會爲該作業中的所有map任務和reduce任務向ResourceManager請求容器Container。
注意:同時也要傳遞心跳信息(每個map任務的數據本地化信息,特別是輸入分片所在的主機和相應機架信息)

分配任務側重:分配到哪、分配的資源

8.1、分配到哪

調用器Scheduler根據這些信息來做調度策略:
首先:Scheduler將任務分配到【數據本地化的節點】
否則:但如果不可能這樣做,調度器進行【機架本地化】的分配

8.2、分配的資源

請求也爲任務指定了內存需求。在默認情況下,map任務和reduce任務都分配到1024MB的內存。
	但這可以通過mapreduce.map.memory.mb和mapreduce.reduce.memory.mb來設置
  TaskTracker和JobTracker之間的通信和任務分配是通過心跳機制按成的。TaskTracker作爲一個單獨的JVM執行一個簡單的循環,主要實現每隔一段時間向JobTracker發送心跳(Heartbeat),以次告訴JobTracker此TaskTracker是否存活,是否準備執行新的任務。JobTracker接收到心跳信息後,如果有待分配的任務,它就會爲TaskTracker分配一個任務,並將分配信息封裝在心跳通信的返回值中返回給TaskTracker。TaskTracker從心跳方法的Response中得知此TaskTracker需要做的事情,如果是一個新的Task,則將它加入本機的任務隊列中

1.4、執行作業

  1. 資源管理器的調度器爲任務分配了容器完畢,MRAppMaster就通過與節點管理器通信來啓動容器(9.a和9.b)

  2. 任務需要的資源進行本地化。
    任務Task由主類YarnChild的Java應用程序執行。
    在YarnChild運行任務之前,首先將任務需要的資源進行本地化(作業的配置、JAR文件和來分佈式緩存的文件)

  3. 運行map任務或reduce任務

1.5、進應和狀態更新

MR作業執行階段的心跳:
11秒:client node 與MRAppMaster檢測Task情況
23秒:Task與MrAppMaster回報任務完成情況
35秒:client node 調用job.waitForCompletion() 檢測作業的完成情況

1)在YARN下運行時,任務每3秒準MRAppMaster彙報進度和狀態,作爲作業的匯聚視圖(aggregate view)
2)客戶端每1秒鐘(通過mapreduce.client.progressmonitor.pollinterval設置)查詢一次MRAppMaster以接收進度更新,通常都會向用戶顯示(訪問8088)。
在這裏插入圖片描述

1.6、作業完成

1)客戶端每5秒鐘通過調用Job的waitForCompletion()來檢查作業是否完成。
查詢的間隔可以通過mapreduce.client.completion.pollinterval屬性進行設置。

2)作業完成後,MRAppMaster和任務容器Container清理其工作狀態,outputCommiter的作業清理方法會被調用。
作業歷史服務器jobhistory保存作業的信息供用戶需要時查詢。

2、配置Yam的Uber mode

【yarn-site.xm1】追加
mapreduce.job.ubertask.enab1e;默認值false;true啓用user功能。
<!--配置uber mode可用-->
<property>
	<name>mapreduce.job.ubertask.enable</name>
	<value>true</value>
</property>

uber的默認配置
mapreduce.job.ubertask.maxmaps 最大map數,默認值:9
mapreduce.job.ubertask.maxreduces 最大reduce數,默認值:1

在這裏插入圖片描述

3、MapReduce完整的shuffle流程

3.1、什麼是Shufle

Mapreduce 確保每個 reducer 的輸入都是按鍵排序的。系統執行排序的過程(即將 map輸出作爲輸入傳給 reducer)稱爲 shuffle。

Shuffle的本義是洗牌、混洗,把一組有一定規則的數據儘量轉換成一組無規則的數據,越隨機越好。

MapReduce中的Shuffle更像是洗牌的逆過程,把一組無規則的數據儘量轉換成一組具有一定規則的數據。

3.2、MapReduce爲什麼需要Shuffle過程?

MapReduce計算模型一般包括兩個重要的階段:

  1. Map是映射,負責並行的數據過濾、處理;
  2. Reduce是規約,負責數據的計算歸併。
    Reduce的數據來源於Map,Map的輸出即是Reduce的輸入,Reduce需要通過Shuffle來獲取數據。

從Map輸出到Reduce輸入的整個過程可以廣義地稱爲Shuffle。

Shuffle橫跨Map端和Reduce端,在Map端包括Spill過程,在Reduce端包括copy、merge、sort、reduce過程。

3.3、MapReduce完整的Shuffle過程

在這裏插入圖片描述

partition的目的是將記錄劃分到不同的Reducer上去,以期望能夠達到負載均衡,以後的Reducer就會根據partition來讀取自己對應的數據

在這裏插入圖片描述

3.3.1、Map端的Shufle

Map端會處理輸入數據併產生中間結果,這個中間結果會寫到本地磁盤,而不是HDFS。

  1. 每個Map的輸出會先寫到內存緩衝區中,同時進行二次排序,首先根據數據所屬的partition進行排序,然後每個partition中的數據再按key來排序。
  2. 接着運行本地combiner(如果設置了的話),combiner的本質也是一個Reducer,其目的是對將要寫入到磁盤上的文件先進行一次處理,這樣,寫入到磁盤的數據量就會減少。
  3. 當寫入的數據達到設定的閾值時,系統將會啓動一個線程將緩衝區的數據寫到磁盤,這個過程叫做spill(寫溢)。
  4. 最後將數據寫到本地磁盤產生spill文件(spill文件保存在{mapred.local.dir}指定的目錄中,Map任務結束後就會被刪除。
  5. 最終,每個Map任務可能產生多個spill文件,在每個Map任務完成前,會通過多路歸併算法將這些spill文件歸併成一個文件。至此,Map的shuffle過程就結束了。

3.3.2、Reduce端的Shufle

Reduce端的shuffle主要包括三個階段,copy、sort(merge)和reduce。

  1. copy階段: 首先要將Map端產生的輸出文件拷貝到Reduce端,但每個Reducer如何知道自己應該處理哪些數據呢?因爲Map端進行partition的時候,實際上就相當於指定了每個Reducer要處理的數據(partition就對應了Reducer),所以Reducer在拷貝數據的時候只需拷貝與自己對應的partition中的數據即可。ReduceTask 從各個 MapTask 上遠程拷貝一片數據,並針對某一片數據,如果其大小超過一定閾值,則寫到磁盤上,否則直接放到內存中。
  2. Merge 階段:在遠程拷貝數據的同時,ReduceTask 啓動了兩個後臺線程對內存和磁盤上的文件進行合併,以防止內存使用過多或磁盤上文件過多。
  3. Sort 階段:按照 MapReduce 語義,用戶編寫 reduce()函數輸入數據是按 key 進行聚集的一組數據。爲了將 key 相同的數據聚在一起,Hadoop 採用了基於排序的策略。由於各個 MapTask 已經實現對自己的處理結果進行了局部排序,因此,ReduceTask 只需對所有數據進行一次歸併排序即可。
  4. Reduce 階段:reduce()函數將計算結果寫到 HDFS 上。

4、MapReduce整體流程詳解

在這裏插入圖片描述

4.1、切片

  • 在FileInputFormat中,計算切片大小的邏輯:Math.max(minSize, Math.min(maxSize,blockSize))
  • minSize的默認值是1,而maxSize的默認值是long類型的最大值,即可得切片的默認大小是blockSize(128M)
  • maxSize參數如果調得比blocksize小,則會讓切片變小,而且就等於配置的這個參數的值
  • minSize參數調的比blockSize大,則可以讓切片變得比blocksize還大
  • hadoop爲每個分片構建一個map任務,可以並行處理多個分片上的數據,整個數據的處理過程將得到很好的負載均衡,因爲一臺性能較強的計算機能處理更多的數據分片.
  • 分片也不能切得太小,否則多個map和reduce間數據的傳輸時間,管理分片,構建多個map任務的時間將決定整個作業的執行時間.(大部分時間都不在計算上)

如果文件大小小於128M,則該文件不會被切片,不管文件多小都會是一個單獨的切片,交給一個maptask處理.如果有大量的小文件,將導致產生大量的maptask,大大降低集羣性能.

大量小文件的優化策略:

(1) 在數據處理的前端就將小文件整合成大文件,再上傳到hdfs上,即避免了hdfs不適合存儲小文件的缺點,又避免了後期使用mapreduce處理大量小文件的問題。(最提倡的做法)

(2)小文件已經存在hdfs上了,可以使用另一種inputformat來做切片(CombineFileInputFormat),它的切片邏輯和FileInputFormat(默認)不同,它可以將多個小文件在邏輯上規劃到一個切片上,交給一個maptask處理。

(3)儘量避免大量小文件,不生成小文件。

4.2、環形緩存區

  • 經過map函數的邏輯處理後的數據輸出之後,會通過OutPutCollector收集器將數據收集到環形緩存區保存。
  • 環形緩存區的大小默認爲100M,當保存的數據達到80%時,就將緩存區的數據溢出到磁盤上保存。

4.3、溢出

  • 環形緩存區的數據達到其容量的80%時就會溢出到磁盤上進行保存,在此過程中,程序會對數據進行分區(默認HashPartition)和排序(默認根據key進行快排)
  • 緩存區不斷溢出的數據形成多個小文件

4.4、合併

  • 溢出的多個小文件各個區合併在一起(0區和0區合併成一個0區),形成大文件
  • 通過歸併排序保證區內的數據有序

4.5、shuffle

從過程2到過程7之間,即map任務和reduce任務之間的數據流稱爲shuffle(混洗),而過程5最能體現出混洗這一概念。
一般情況下,一個reduce任務的輸入數據來自與多個map任務,多個reduce任務的情況下就會出現如過程5所示的,每個reduce任務從map的輸出數據中獲取屬於自己的那個分區的數據。

4.6、合併

運行reducetask的節點通過過程5,將來自多個map任務的屬於自己的分區數據下載到本地磁盤工作目錄。這多個分區文件通過歸併排序合併成大文件,並根據key值分好組(key值相同的,value值會以迭代器的形式組在一起)。

4.7、reducetask

reducetask從本地工作目錄獲取已經分好組並且排好序的數據,將數據進行reduce函數中的邏輯處理。

4.8、輸出

每個reducetask輸出一個結果文件。

覺得有幫助的,請多多支持博主,點贊關注哦~

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