2.MR理論概念

下面我們看官方給出的例子:
1:將Block塊分割成三個Split
2:每個Split對應一個mapper
3: 三個mapper輸出結果進行Shuffling,每個map的輸出只是簡單的key-value而非key-valuelist,所以洗牌的工作就是將map輸出轉化爲reducer的輸入的過程。在reducer開始之前shuffle要做的事情分爲兩步copy和sort 階段。

 ====================================================================================================================================================
 ====================================================================================================================================================

主要的思想是分而治之(divide and conquer),分治算法。
將一個大的問題切分成很多小的問題,然後在集羣中的各個節點上執行,這既是Map過程。在Map過程結束之後,會有一個Ruduce的過程,這個過程即將所有的Map階段產出的結果進行彙集。
寫MapReduce程序的步驟:
1.把問題轉化爲MapReduce模型
2.設置運行的參數
3.寫map類
4.寫reduce類
例子:統計單詞個數
將文件拆分成splits,每個文件爲一個split,並將文件按行分割形成<key,value>對,MapReduce框架自動完成,其中行偏移量(即key值)包括了回車所佔的字符數



將分割好的<key,value>對交給用戶定義的map方法(TokenizerMapper)進行處理,生成新的<key,value>對。

得到map方法輸出的<key,value>對後,Mapper會將它們按照key值進行排序,並執行Combine過程,將key至相同value值累加,得到Mapper的最終輸出結果。

Reducer先對從Mapper接收的數據進行排序,再交由用戶自定義的reduce方法(IntSumReducer)進行處理,
得到新的<key,value>對,並作爲WordCount的輸出結果



 ====================================================================================================================================================
 ====================================================================================================================================================


那到底什麼是Shuffle呢?Shuffle的中文意思是“洗牌”,如果我們這樣看:一個map產生的數據,結果通過hash過程分區卻分配給了不同的reduce任務,是不是一個對數據洗牌的過程呢?

默認的partitioner是HashPartitioner,它對每條記錄的鍵進行哈希操作以決定該紀錄屬於哪個分區,每個分區對應一個reduce任務,所以分區數等於reduce個數

輸入分片(input split)在進行map計算之前,mapreduce會根據輸入文件計算輸入分片(input split),每個輸入分片(input split)針對一個map任務,輸入分片(input split)存儲的並非數據本身,而是一個分片長度和一個記錄數據的位置的數組,輸入分片(input split)往往和hdfs的block(塊)關係很密切,假如我們設定hdfs的塊的大小是64mb,如果我們輸入有三個文件,大小分別是3mb、65mb和127mb,那麼mapreduce會把3mb文件分爲一個輸入分片(input split),65mb則是兩個輸入分片(input split)而127mb也是兩個輸入分片(input split),換句話說我們如果在map計算前做輸入分片調整,例如合併小文件,那麼就會有5個map任務將執行,而且每個map執行的數據大小不均,這個也是mapreduce優化計算的一個關鍵點。

map階段就是程序員編寫好的map函數了,因此map函數效率相對好控制,而且一般map操作都是本地化操作也就是在數據存儲節點上進行;

combiner階段:combiner階段是程序員可以選擇的,combiner其實也是一種reduce操作,因此我們看見WordCount類裏是用reduce進行加載的。Combiner是一個本地化的reduce操作,它是map運算的後續操作,主要是在map計算出中間文件前做一個簡單的合併重複key值的操作,例如我們對文件裏的單詞頻率做統計,map計算時候如果碰到一個hadoop的單詞就會記錄爲1,但是這篇文章裏hadoop可能會出現n多次,那麼map輸出文件冗餘就會很多,因此在reduce計算前對相同的key做一個合併操作,那麼文件會變小,這樣就提高了寬帶的傳輸效率,畢竟hadoop計算力寬帶資源往往是計算的瓶頸也是最爲寶貴的資源,但是combiner操作是有風險的,使用它的原則是combiner的輸入不會影響到reduce計算的最終輸入,例如:如果計算只是求總數,最大值,最小值可以使用combiner,但是做平均值計算使用combiner的話,最終的reduce計算結果就會出錯。

shuffle階段將map的輸出作爲reduce的輸入的過程就是shuffle了,這個是mapreduce優化的重點地方。這裏我不講怎麼優化shuffle階段,講講shuffle階段的原理,因爲大部分的書籍裏都沒講清楚shuffle階段。Shuffle一開始就是map階段做輸出操作,一般mapreduce計算的都是海量數據,map輸出時候不可能把所有文件都放到內存操作,因此map寫入磁盤的過程十分的複雜,更何況map輸出時候要對結果進行排序,內存開銷是很大的,map在做輸出時候會在內存裏開啓一個環形內存緩衝區,這個緩衝區專門用來輸出的,默認大小是100mb,並且在配置文件裏爲這個緩衝區設定了一個閥值,默認是0.80(這個大小和閥值都是可以在配置文件裏進行配置的),同時map還會爲輸出操作啓動一個守護線程,如果緩衝區的內存達到了閥值的80%時候,這個守護線程就會把內容寫到磁盤上,這個過程叫spill,另外的20%內存可以繼續寫入要寫進磁盤的數據,寫入磁盤和寫入內存操作是互不干擾的,如果緩存區被撐滿了,那麼map就會阻塞寫入內存的操作,讓寫入磁盤操作完成後再繼續執行寫入內存操作,前面我講到寫入磁盤前會有個排序操作,這個是在寫入磁盤操作時候進行,不是在寫入內存時候進行的,如果我們定義了combiner函數,那麼排序前還會執行combiner操作。每次spill操作也就是寫入磁盤操作時候就會寫一個溢出文件,也就是說在做map輸出有幾次spill就會產生多少個溢出文件,等map輸出全部做完後,map會合並這些輸出文件。這個過程裏還會有一個Partitioner操作,對於這個操作很多人都很迷糊,其實Partitioner操作和map階段的輸入分片(Input split)很像,一個Partitioner對應一個reduce作業,如果我們mapreduce操作只有一個reduce操作,那麼Partitioner就只有一個,如果我們有多個reduce操作,那麼Partitioner對應的就會有多個,Partitioner因此就是reduce的輸入分片,這個程序員可以編程控制,主要是根據實際key和value的值,根據實際業務類型或者爲了更好的reduce負載均衡要求進行,這是提高reduce效率的一個關鍵所在。到了reduce階段就是合併map輸出文件了,Partitioner會找到對應的map輸出文件,然後進行復制操作,複製操作時reduce會開啓幾個複製線程,這些線程默認個數是5個,程序員也可以在配置文件更改複製線程的個數,這個複製過程和map寫入磁盤過程類似,也有閥值和內存大小,閥值一樣可以在配置文件裏配置,而內存大小是直接使用reduce的tasktracker的內存大小,複製時候reduce還會進行排序操作和合並文件操作,這些操作完了就會進行reduce計算了。

reduce階段:和map函數一樣也是程序員編寫的,最終結果是存儲在hdfs上的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章