分片,map,分區,排序,分組,歸約,合併,合併,排序,歸約,合併,reduce算法
1、關於Reducer與輸出文件安全
MR中Reducer默認值爲一,當job.setNumReduceTasks(2)時,在Eclipse中運行只有一個輸出文件。網絡
將代碼導出成JAR包(代碼中要添加job.setJarByClass(*.class); ),放入Linux中,執行hadoop jar *.jar,纔會生成兩個輸出文件app
在Eclipse中運行兩分區兩Reducer任務會報錯?框架
2、FS的模式:函數
hadoop dfsadmin -safemode valueoop
參數value的說明以下:
enter - 進入安全模式
leave - 強制NameNode離開安全模式
get - 返回安全模式是否開啓的信息
wait - 等待,一直到安全模式結束。spa
3、機制:Job,JobTracker,TaskTracker,HDFS線程
1.在客戶端啓動一個做業Job。3d
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查詢狀態時,它將得知任務已完成,便顯示一條消息給用戶。
1、Mapper個數由文件塊決定,Reducer個數能夠設定。
2、Shuffle用來鏈接Mapper和Reducer,包括Mapper階段的Shuffle,即Mapper的寫入,Reducer階段的Shuffle,即Reduce的讀入。前者爲單個Mapper上的排序、歸約、合併。後者爲全部Mapper上的排序、歸約、合併。
3、Mapper階段將同一個key分配到同一個分區(分區是無序的?),Reducer階段一個分區對應一個Reducer,reduce處理的數據是有序的
5、單個Reducer內的數據是有序的,但Reducer之間是無序的,默認是一個Reducer
6、一個Mapper任務能夠調用屢次map函數,一個Reducer任務能夠接受多個Mapper任務,屢次調用reduce函數
7、sort排序、combiner歸約、merger合併
1. Mapper任務處理
1.1 讀取輸入文件內容,解析成key、value對。對輸入文件的每一行,解析成key、value對。每個鍵值對調用一次map函數。
1.2 map函數。
1.3 對輸出的key、value進行分區。
1.4 對不一樣分區的數據,按照key進行排序、分組。相同key的value放到一個集合中。
1.5 (可選)分組後的數據進行歸約(combine)。
2.Reducer任務處理
2.1 對一個或多個map任務的輸出,按照不一樣的分區,經過網絡copy到不一樣的Reducer節點。
2.2 在一個Reducer節點上未來自同一分區的數據進行合併、排序,再交給reduce函數
2.3 把reduce的輸出保存到文件中。
///////////////////////////////////////
Map階段
分片(Split):map階段的輸入一般是HDFS上文件,在運行Mapper前,FileInputFormat會將輸入文件分割成多個split ——1個split至少包含1個HDFS的Block(默認爲64M);而後每個分片運行一個map進行處理。
執行(Map):對輸入分片中的每一個鍵值對調用map()函數進行運算,而後輸出一個結果鍵值對。
Partitioner:對map()的輸出進行partition,即根據key或value及reduce的數量來決定當前的這對鍵值對最終應該交由哪一個reduce處理。默認是對key哈希後再以reduce task數量取模,默認的取模方式只是爲了不數據傾斜。而後該key/value對以及partitionIdx的結果都會被寫入環形緩衝區。
溢寫(Spill):map輸出寫在內存中的環形緩衝區,默認當緩衝區滿80%,啓動溢寫線程,將緩衝的數據寫出到磁盤。
Sort:在溢寫到磁盤以前,使用快排對緩衝區數據按照partitionIdx, key排序。(每一個partitionIdx表示一個分區,一個分區對應一個reduce)
Combiner:若是設置了Combiner,那麼在Sort以後,還會對具備相同key的鍵值對進行合併,減小溢寫到磁盤的數據量。
合併(Merge):溢寫可能會生成多個文件,這時須要將多個文件合併成一個文件。合併的過程當中會不斷地進行 sort & combine 操做,最後合併成了一個已分區且已排序的文件。
Shuffle階段:廣義上Shuffle階段橫跨Map端和Reduce端,在Map端包括Spill過程,在Reduce端包括copy和merge/sort過程。一般認爲Shuffle階段就是將map的輸出做爲reduce的輸入的過程
Copy過程:Reduce端啓動一些copy線程,經過HTTP方式將map端輸出文件中屬於本身的部分拉取到本地。Reduce會從多個map端拉取數據,而且每一個map的數據都是有序的。
Merge過程:Copy過來的數據會先放入內存緩衝區中,這裏的緩衝區比較大;當緩衝區數據量達到必定閾值時,將數據溢寫到磁盤(與map端相似,溢寫過程會執行 sort & combine)。若是生成了多個溢寫文件,它們會被merge成一個有序的最終文件。這個過程也會不停地執行 sort & combine 操做。
Reduce階段:Shuffle階段最終生成了一個有序的文件做爲Reduce的輸入,對於該文件中的每個鍵值對調用reduce()方法,並將結果寫到HDFS。