hadoop1中mapreduce原理詳解


剖析Mapreduce作業運行機制:原理如下圖:

原理圖的解釋的可以分為以下幾個部分

1、客戶端提交一個mapreduce的jar包給JobClient

2、JocClient通過RPC和JobTracker進行通信,返回一個存放jar包的地址(HDFS)

3、JobClient將jar包寫入到HDFS當中(path=hdfs上的地址(這個地址是有第二步的JobTracker返回的)+JobId)

  將運行作業所需要的資源文件復制到HDFS上,包括MapReduce程序打包的JAR文件、配置文件和客戶端計算所得的輸入划分信息。這些文件都存放在JobTracker專門  為該作業創建的文件夾中。文件夾名為該作業的Job ID。JAR文件默認會有10個副本(mapred.submit.replication屬性控制);輸入划分信息告訴了JobTracker應該為這個   作業啟動多少個map任務等信息

4、開始提交任務(任務的描述信息:包括jobid,jar存放的位置,配置信息等等)

  JobClient調用JobTracker的submitJob()方法提交任務

5、JobTracker進行初始化任務

  JobTracker會把提交的作業放在一個內部隊列中,交由作業調度器來進行調度,任務的初始化包括創建一個表示運行的作業的對象——封裝任務和記錄信息,以便跟蹤  任務的狀態和信息。

6、讀取HDFS上要處理的文件,開始計算輸入分片,每一個分片對應一個MapperTask

  當作業調度器根據自己的調度算法調度到該作業時,會根據輸入划分信息為每個切片啟動一個MapperTask任務

7、TaskTracker通過心跳機制領取任務(任務的描述信息)

  map任務不是隨隨便便地分配給某個TaskTracker的,這里有個概念叫:數據本地化(Data-Local)。意思是:將map任務分配給含有該map處理的的TaskTracker上。同時將程序JAR包復制到該TaskTracker上來運行,這叫“運算移動,數據不移動”。而分配reduce任務時並不考慮數據本地化。TaskTracker每隔一段時間會給 JobTracker發送一個心跳,告訴JobTracker它依然在運行,同時心跳中還攜帶着很多的信息,比如當前map任務完成的進度等信息。當JobTracker收到作業的最后一任務完成信息時,便把該作業設置成“成功”。當JobClient查詢狀態時,它將得知任務已完成,便顯示一條消息給用戶

8、下載所需的jar,配置文件

9、TaskTracker啟動一個java child子進程,用來執行具體的任務(MapperTask或ReducerTask)

  map函數端的執行過程:

  a:每個輸入分片會讓一個map任務處理,默認情況下,以HDFS的一個快的大小為一個分片,map輸出的結果暫且放在一個環形內存緩沖區中(該緩沖區的大小默認為100M,由io.sort.mb屬性控制),當該緩沖區快要溢出時(默認為緩沖區大小的80%,由io.sort。spill。percent屬性控制),會在本地文件系統中創建一個溢出文件,將該緩沖區的數據寫入這個文件

  b:在寫入磁盤之前,線程首先根據reduce任務的數目將數據划分為相同數目的分區,也就是一個reduce任務對應一個分區的數據,這樣做是為了避免有些reduce任務分配到大量數據,而有些reduce任務卻分配到很少數據,其實分區就是對數據進行hash的過程,然后對每個分區中的數據進行排序,如果此時設置了Combiner,將排序后的結果進行Combiner操作,這樣做的目的是讓盡可能少的數據寫入到磁盤。

  c:當map任務輸出最后一個記錄時,可能會有很多的溢出文件,這時需要將這些文件合並,合並的過程會不斷的進行排序和Combiner操作,目的有兩個:1、盡量減少每次寫入磁盤的數據量,2、盡量減少下一次復制階段網絡傳輸的數據量,最后合並成一個已分區已排序的文件,為了減少網絡傳輸的數據量,可以將數據進行雅俗,只要將mapred.compress.map.out設置為true就行了

  d:將分區中的數據拷貝給相對應的reduce任務,有人可能會問:分區中的數據怎么知道它對應的reduce是哪個呢?其實map任務一直和其父TaskTracker保持聯系,而TaskTracker又一直和JobTracker保持心跳。所以JobTracker中保存了整個集群中的宏觀信息。只要reduce任務向JobTracker獲取對應的map輸出位置就ok了哦。

  reduce函數端執行過程

  a:reduce會收到不同map任務傳來的數據,並且每個map傳來的數據都是有序的,如果reduce端接受的數據量相當小,則直接存儲在內存中(緩沖區大小由mapred.job.shuffle.input.buffer.percent屬性控制,表示用作此用途的堆空間的百分比),如果數據量超過了該緩沖區大小的一定比例(由mapred.job.shuffle.merge.buffer.percent決定),則對數據合並后溢寫到磁盤中。

  b:伴隨着溢寫文件的增多,后台線程會將它們合並成一個更大的有序的文件,這樣做是為了給后面的合並節省時間,其實不管在map端還是reduce端,MapReduce都是反復的執行排序,合並操作,

  c:合並的過程中會產生許多的中間文件(寫入磁盤了),但MaoReduce會讓寫入磁盤的數據盡可能的少,並且最后一次合並的結果並沒有寫入磁盤,而是直接輸入到reduce函數。

10、將結果寫入到HDFS當中


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com