1. 程式人生 > >MapReduce之全流程講解

MapReduce之全流程講解

週末心情好,來理下整個MapReduce的工作流程,方便記憶和理解。

hadoop四大元件之一的MapReduce分散式計算系統,和HDFS-分散式儲存系統,YARN-分散式作業系統(主要負責資源排程,相當於作業系統)三分天下,那麼我們就將資料從HDFS輸入到最後輸出到HDFS來詳細聊一聊Mapreduce的工作機制。

首先,上圖。光說不上圖都是耍流氓。資料的供給交給HDFS,資源的調配交給YARN,對資料進行鬼斧神工處理的部分就交給mapreduce了。mapreduce一般來說,可以細分為十大元件,分別為:TextInputFormat,LineRecorderReader, Mapper,shuffle(partition,sort,combiner),GroupComparator,Reducer,LineRecorderWriter,TextOutputFormat。首先我們對這是個元件做一個大概的解釋:


TextInputFormat和LineRecorderReader,輸入元件,主要負責從HDFS讀取資料,預設是一個檔案一行一行的讀取,獲取的資料進入map進行處理。

LineRecorderWriter和TextOutputFormat,輸出元件,主要負責接收reducer處理好的資料寫入DHFS,一般有多少個reduceTask就會生成幾個檔案。

Mapper,mapreduce程式設計框架中業務邏輯編寫的第一個元件。mapreduce預設接收到的資料,以每行字元的偏移量為key,\t分隔,之後的其他內容為value,一般讀取資料進行處理的時候,都需要將value進行切割,放在相應型別的陣列中進行處理。

Reducer,mapreduce程式設計框架中業務邏輯編寫的最後一個元件--自定義輸出除外。reducer接收到資料,是經過mapper處理,shuffle後,分割槽好了的資料。預設reducer會根據分割槽,key值自然排序將資料交給輸出元件,方法呼叫為 context.wirte(key,value)。

Shuffle三大元件:

1、partitioner---分割槽元件。底層呼叫getPartition方法,通過計算key得hash值與reducetast個數的商,將不同key值得鍵值對劃分到各個分割槽,可以有效的避免reduce階段出現的資料傾斜和提高整體執行效率。

2、sort---排序元件,針對分割槽之後的資料,進行一個自然順序排序。預設採用的排序演算法有快速排序和遞迴排序。

3、combiner---區域性合併元件。該元件使用者不指定的話,是不存在的。主要的用途是用來減緩reduce階段的壓力。也可以根據使用者自己的需求,進行特殊的合併。

GroupComparator---分組元件。通常處理業務邏輯的時候,會碰到既需要分組,又需要排序的情況,比如常見的求某些範圍內的TopN的問題。這時,常常需要我們根據排序規則,自定義分組,否則當排序規則與分組規則發生衝突的時候,mapreduce程式會報錯或者輸出錯誤的資料。詳細參考我的另一篇博文--mapreduce中分組排序的一些認識。

下面,我們以經典的單詞計數程式為例,來說明下這十大元件是怎麼協調工作的。

首先,mapreduce通過TextInoutFormat元件,呼叫LineRecordReader中的nextKeyValue方法,一行一行的讀取資料,當nextKeyvalue的值返回false時,表示讀取完畢。讀取的資料,會一行行的傳遞給mapper,mapper收到資料-value,以及資料行的其實偏移量-key,提供一個map方法,供開發者進行業務邏輯的編寫。在wordCount程式中,我們將獲取的每一行資料單獨提取出一個個的單詞,以單詞為key,計算單為1位值。交給shuffle階段。--自定義輸入格式請移步我的另外一篇博文--Mapreduce自定義輸入輸出元件的認識。

然後資料進入shuffle階段。以上說的是一個maptask讀取資料,處理的情況。通常情況下,是有多個maptask共同發生以上的行為,所有的maptask都會輸出一堆的鍵值對,在shuffle階段進行大洗牌。進入了shuffle階段的鍵值對資料,預設情況下,按照預設規則分割槽,自然排序,將相同的key進行合併之後,輸出到reduce階段。在這裡,大神們根據自己的需要,修改分割槽(個數,大小),指定排序(預設情況下是自然排序,並且是一定會執行),進行區域性合併(降低網路資料傳輸)都可以為所欲為。在某些業務邏輯下,涉及到同時自定義分組和排序,就需要使用者編寫自己的GroupComparator。經過shuffle階段洗牌之後的資料,每個分割槽的資料都已經排序好,相同key值的資料被分到同一個reducetask,進行進一步的合併處理。

進入到reducer階段,通過reduce方法,一般是對接收到的鍵值對的value進行邏輯處理。當然這個階段的key值也是可以根據需求進行處理的。之後資料進入通過context.wirte方法進入輸出階段。

最後,LineRecorderWriter和TextOutputFormat元件通過改寫write方法,將資料輸出到指定的位置,輸出成指定的檔案等。

因此,總體來說Mapreduce各個元件之間分工明確,各司其職。但是通過深刻的理解其內部的執行機制,又可以靈活的利用各個元件,根據自己的業務需要,隨意的進行改寫。各個元件之間的界線又變的模糊起來。真是學的越多,越對學習充滿了敬畏。吾生也有涯,而知也無涯,學無止境吧!!!

圖片來自超級大牛中琦2513!!!!