MapReduce工作原理

2021-07-05 09:05:31 字數 2819 閱讀 5879

本文的目錄:

1.mapreduce作業執行流程

2.map、reduce任務中shuffle和排序的過程 

mapreduce作業詳細的執行流程:

流程分析:

1.在客戶端啟動乙個作業。

2.向jobtracker請求乙個job id。

3.將執行作業所需要的資源檔案複製到hdfs上,包括mapreduce程式打包的jar檔案、配置檔案和客戶端計算所得的輸入劃分資訊。這些檔案都存放在jobtracker專門為該作業建立的資料夾中。資料夾名為該作業的job id。jar檔案缺省會有10個副本(mapred.submit.replication屬性控制);輸入劃分資訊告訴了jobtracker應該為這個作業啟動多少個map任務等資訊。

4.jobtracker接收到作業後,將其放在乙個作業佇列裡,等待作業排程器對其進行排程,當作業排程器根據自己的排程演算法排程到該作業時,會根據輸入劃分資訊為每個劃分建立乙個map任務,並將map任務分配給tasktracker執行。對於map和reduce任務,tasktracker根據主機核的數量和記憶體的大小有固定數量的map槽和reduce槽。這裡需要強調的是:map任務不是隨隨便便地分配給某個tasktracker的,這裡有個概念叫:資料本地化(data-local)。意思是:將map任務分配給含有該map處理的資料塊的tasktracker上,同時將程式jar包複製到該tasktracker上來執行,這叫「運算移動,資料不移動」。而分配reduce任務時並不考慮資料本地化。

5.tasktracker每隔一段時間會給jobtracker傳送乙個心跳,告訴jobtracker它依然在執行,同時心跳中還攜帶著很多的資訊,比如當前map任務完成的進度等資訊。當jobtracker收到作業的最後乙個任務完成資訊時,便把該作業設定成「成功」。當jobclient查詢狀態時,它將得知任務已完成,便顯示一條訊息給使用者。

以上是在客戶端、jobtracker、tasktracker的層次來分析mapreduce的工作原理的,下面我們再細緻一點,從map任務和reduce任務的層次來分析分析吧。

2.map、reduce任務中shuffle和排序的過程

流程示意圖:

流程分析:

map端:

1.每個輸入分片會讓乙個map任務來處理,預設情況下,以hdfs的乙個塊的大小(預設為64m)為乙個分片,當然我們也可以設定塊的大小。map輸出的結果會暫且放在乙個環形記憶體緩衝區中(該緩衝區的大小預設為100m,由io.sort.mb屬性控制),當該緩衝區快要溢位時(預設為緩衝區大小的80%,由io.sort.spill.percent屬性控制),會在本地檔案系統中建立乙個溢位檔案,將該緩衝區中的資料寫入這個檔案。

2.在將記憶體緩衝區中的資料寫入磁碟之前,執行緒首先根據reduce任務的數目將資料劃分為相同數目的分割槽,也就是乙個reduce任務對應乙個分割槽的資料。這樣做是為了避免有些reduce任務分配到大量資料,而有些reduce任務卻分到很少資料,甚至沒有分到資料的尷尬局面。其實分割槽就是對資料進行hash的過程。然後對每個分割槽中的資料進行排序,如果此時設定了combiner,將排序後的結果進行combia操作,這樣做的目的是讓盡可能少的資料寫入到磁碟。

3.當map任務輸出最後乙個記錄時,可能會有很多的溢位檔案,

直接將每乙個map生成的眾多spill檔案交給reduce處理不現實,所以在每個map任務結束之後在map的tasktracker上還會執行合併操作(merge),這個操作的主要目的就是將map生成的眾多spill檔案中的資料(此時每個spill中的資料已經經過sort過程,一段範圍的key已經排在一起了)按照劃分重新組織,針對指定的分割槽,從各個spill檔案中拿出屬於同乙個分割槽的所有資料,然後將它們合併在一起,並寫入乙個已分割槽且已排序的map輸出檔案中。為了減少網路傳輸的資料量,這裡可以將資料壓縮,只要將mapred.compress.map.out設定為true就可以了。待唯一的已分割槽且已排序的map輸出檔案寫入最後一條記錄後,map端的shuffle階段就結束了。就進入了reduce端的shuffle階段。

4.將分割槽中的資料拷貝給相對應的reduce任務。有人可能會問:分割槽中的資料怎麼知道它對應的reduce是哪個呢?其實map任務一直和其父tasktracker保持聯絡,而tasktracker又一直和jobtracker保持心跳。所以jobtracker中儲存了整個集群中的巨集觀資訊。只要reduce任務向jobtracker獲取對應的map輸出位置就ok了。

reduce端:

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

2.隨著溢寫檔案的增多,後台執行緒會將它們合併成乙個更大的有序的檔案,這樣做是為了給後面的合併節省時間。其實不管在map端還是reduce端,mapreduce都是反覆地執行排序,合併操作。

3.合併的過程中會產生許多的中間檔案(寫入磁碟了),但mapreduce會讓寫入磁碟的資料盡可能地少,並且最後一次合併的結果並沒有寫入磁碟,而是直接輸入到reduce函式。

本文出處:

map reduce工作原理

下面的圖來自南京大學計算機系黃宜華老師開設的mapreduce課程的課件,這裡稍作整理和 總結。本文旨在對接觸了mapreduce之後,但是對mapreduce的工作流程仍不是很清楚的人員,當然包括博主自己,希望與大家一起學習。mapreduce借鑑了函式式程式語言lisp中的思想,lisp lis...

MapReduce工作原理

map reduce框架的運作完全基於對,即資料的輸入是一批對,生成的結果也是一批對,只是有時候它們的型別不一樣而已。key和value的類由於需要支援被序列化 serialize 操作,所以它們必須要實現writable介面,而且key的類還必須實現writablecomparable介面,使得可...

MapReduce工作原理

一切都是從最上方的user program開始的,user program鏈結了mapreduce庫,實現了最基本的map函式和reduce函式。mapreduce庫先把user program的輸入檔案劃分為m份 m為使用者定義 每乙份通常有16mb到64mb,如圖左方所示分成了split0 4 ...