1. 程式人生 > >深入學習Hadoop之第二篇——MapReduce

深入學習Hadoop之第二篇——MapReduce

概念:MapReduce是一種資料處理的程式設計模型

一、Map

1.資料流:

一個MapReduce job是客戶端所執行的work的單元,它包括:輸入資料、MapReduce程式以及配置資訊;

Hadoop把MapReduce job分割為更小的tasks(map tasks和reduce tasks)來執行,這些tasks被YARN排程在叢集節點上執行;如果一個task失敗了,它會被自動排程到其他節點上重新執行;

Hadoop把MapReduce的輸入資料分割成固定長度的片段,稱作輸入切片或切片;Hadoop為每一個切片建立一個map task,並由該task來執行使用者定義的map函式從而處理切片中的每條記錄;擁有許多切片意味著處理每個切片的時間少於處理整個輸入的時間。因此,如果並行處理每個分片,且每個切片比較小,那麼整個處理過程將獲得比較好的負載均衡;因為在一個job的執行過程中,一臺更快的機器比慢的機器處理更多的切片,並且是按比例的;即使使用同樣的機器,失敗的程序和其他並行執行的jobs也能夠達到滿意的負載均衡;而且隨著切片的粒度更細負載均衡的會更高;
另一方面,如果切片粒度太細,那麼管理切片的總時間和構建map任務的總時間將決定整個job的執行時間。

對於大多數job來說,一個合理的切片大小趨向於HDFS的block size,預設是128MB,不過可以針對叢集調整這個預設值(新建的所有檔案),或對新建的每個檔案具體而定。

關於切片大小的具體分析:

如果切片大小不等於block size,
1. 切片大小>block size ;
每個切片中的資料要存放在兩個甚至更多的block中,然而對於HDFS中任意一個節點基本上都不可能同時擁有這兩個block
,因此切片中的部分資料需要通過網路傳輸到map task節點,與使用本地資料執行整個map task相比,效率很低。
2. 切片大小<block size
浪費空間,一個切片放入一個block中,block卻仍留有餘地;


2.資料本地化優化

Hadoop在存有輸入資料(HDFS中的資料)的節點上執行map task,可以獲得最佳效能,這就是所謂的"資料本地化優化",因為它無需使用寶貴的叢集頻寬資源。但是,有時對於一個map task的輸入來說,存有某個HDFS block副本的三個節點可能正在執行其他map tasks,此時作業排程需要在三個副本中的某個資料尋求其所在rack中其他空閒的機器來執行該map task ;僅僅在非常偶然的情況下(該情況基本不會發生),會使用其他rack上的機器執行該map task,這將導致rack間的網路傳輸 (圖1列出了以上3種情況)。


圖1. a代表本地資料,b代表本rack上的資料,c代表其他rack上的資料

map task把其輸出寫入本地磁碟,而非HDFS。因為map的輸出只是中間結果:該中間結果由reduce task處理後才產生最終輸出結果,而且一旦job執行完成,map的輸出結果就可以刪除。因此把它存在HDFS中並實現備份,難免小題大做。
如果該節點上執行的map task在將map中間結果傳送到reduce task之前failed,Hadoop會在另一個節點上重新執行這個map task以再次構建map中間結果;

二、Reduce

reduce任務並不具備資料本地化的優勢————單個reduce task的input通常來自於所有mapper的輸出;
因此,排過序的map output需要通過網路傳輸傳送到執行reduce task的節點。資料在reduce端合併,然後由使用者定義的reduce函式處理(圖2,3,4顯示了具體情況)。


圖2.單個Reducer的資料流


圖3.多個Reducer的資料流


圖4.無Reducer的資料流

reduce的output通常儲存在HDFS中以實現可靠儲存:對於每個reduce output的HDFS block,第一個副本儲存在本地節點上,其他副本儲存在其他rack的節點上。因此將reduce的output寫入HDFS確實需要佔用網路頻寬,但這與正常的HDFS流水線寫入的消耗一樣。

reduce的task數量並非由輸入資料的大小決定,而是獨立指定的。
如果有多個reduce tasks,每個map task就會針對map output進行partition,即為每個reduce task建一個分割槽。分割槽由使用者定義的parttition函式控制,但通常用預設的partitioner通過hash函式來分割槽很高效。

combiner函式:
叢集上的可用頻寬限制了MapReduce作業的數量,因此儘量避免map和reduce task之間的資料傳輸是有利的。combiner實際上是一個本地的reducer。combiner作為一個優化方案,有些時候並不能用,比如求均值。