Hadoop之MapReduce工作原理
Map階段
①輸入分片(inputsplit),這個時候也就是輸入資料的時候,這時會進行會通過內部計算對資料進行邏輯上的分片。預設情況下這裡的分片與HDFS中檔案的分塊是一致的。每一個邏輯上的分片也就對應著一個mapper任務。
②Mapper將切片的資料輸入到map函式中進行處理。
③Buffer函式將結果輸出首先放入buffer(緩衝區)中從而為後面的操作(也就是寫入硬碟)做準備。這裡著重介紹一下buffer這個東西。Buffer從邏輯上來說是一個環形的緩衝區預設大小為100M,當第一次輸入的資料超過它容量的80%這個閾值的時候(80%是它的溢寫比)就會自動的寫入硬碟。就在它寫入硬碟的時候程式會繼續往剩餘的20%的空間中寫資料。又由於80%的那些輸入也會輸入到磁碟中所以這樣可以動態的寫入更多的資料。但是如果一旦將整個緩衝區寫滿的話,寫入程式將會掛起一直等到緩衝環中的資料都寫完了寫入程式將會再次啟動開始向緩衝環中寫資料。
⑤溢寫(spill),在達到緩衝環容量的閾值時,緩衝環中的內容會寫到硬碟上。這個過程叫做溢寫。這時會伴隨著一些列的操作,分割槽、排序、合併的操作。又,每一個溢寫操作會對應生成一個檔案。也就是一個mapperTask會對應著多次溢寫也就會處理多個檔案。下面依次解釋名詞。
分割槽(partition):預設的分割槽是hash分割槽這樣會保證所有相同的key就會在儲存在一起。當然我們可以基於各種意義進行分割槽。這樣的話具有相同意義的kv對就會儲存在一起。同時指出一個分割槽就會對應一個Reducer(不管key是否相同他們只要在同一個分割槽內那麼就會被一個Reducer所獲取)。
排序(Sort)
java.lang.ClassCastException: class statisticScore.FlowInfo at java.lang.Class.asSubclass(Unknown Source) at org.apache.hadoop.mapred.JobConf.getOutputKeyComparator(JobConf.java:887) at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.init(MapTask.java:1004) at org.apache.hadoop.mapred.MapTask.createSortingCollector(MapTask.java:402) at org.apache.hadoop.mapred.MapTask.access$100(MapTask.java:81) |
合併(Combiner):這時程式在後臺啟動一個執行緒Combiner,提前將key值相同的資料合併起來可以減少往硬碟上寫資料的量節省了空間,另一方面這些合併的資料會通過網路傳輸到Reducer相關的節點上這樣的話就會節省網路的開銷。Combiner的本質是一個Reducer它的合併操作也是一個Reduce操作。但是這樣做的先決條件就是我們的任務在合併之後最終的結果不會改變。如果提前做Reducer優化而影響到結果計算的話那麼就不能做提前優化。
⑥歸併
將Splii寫入磁碟形成的小檔案合併成為一個大的檔案。由於歸併最後的檔案的資料呈現形式不是前面的小檔案簡單的相加。所以這時又會將分將前面的分割槽,排序與合併。當然這裡的排序與前面溢寫時候的排序有所不同,而是將前面的幾個區域性有序的檔案合併成一個全域性有序的大檔案。此時Combiner後臺執行緒任然可能在做提前的優化合並。(讀到這裡有點費解到底是大檔案好還是小檔案好?)
Reduce階段
⑦獲取資料(fetch)reduce會主動向map階段產生的資料中獲取屬於自己的資料,也就是每個Reducer對應的那些特定分割槽(partitioner)的資料。
⑧歸併(merge)將這些拿到零散的資料再次歸併,與前面的歸併不同的是這裡的歸併產生的並不是一個大檔案,順便這裡產生的資料在記憶體和硬碟上都有一份。
⑨分組(group),分組和分割槽是不同的。分割槽的目的是根據key值來決定Mapper輸出的記錄會被哪一個Reducer所獲取。分組常常是在分割槽內部進行的,在一個分割槽內相同的key可以分為一組。
⑩Reducer將這些資料輸入reduce函式中進行處理計算最後輸出結果。有幾個Reducer也就會對應的輸出到幾個檔案中。
Shuffle階段
上述過程的③到⑨
數量關係的總結
- 一個Splie對應一個MapperTask。
- 一個MapperTask會有多次溢寫,一次溢寫對應著一個檔案,所以一個MapperTask對應著多個檔案。
- 一個分割槽對應著一個Reducer,又一個Reducer對應著一個寫出檔案所以一個分割槽對應著一個寫出檔案。
- 一個分割槽中可能存在多個key,一個key又可以劃分為一個分組所以一個分割槽可以對應多個分組。
- 在Reducer階段的merge形成的資料在記憶體中和磁碟中都有所以有兩份。