MapReduce例項淺析
Hadoop Map/Reduce是一個使用簡易的軟體框架,基於它寫出來的應用程式能夠執行在由上千個商用機器組成的大型叢集上,並以一種可靠容錯的方式並行處理上T級別的資料集。
一個Map/Reduce 作業(job) 通常會把輸入的資料集切分為若干獨立的資料塊,由 map任務(task)以完全並行的方式處理它們。框架會對map的輸出先進行排序, 然後把結果輸入給reduce任務。通常作業的輸入和輸出都會被儲存在檔案系統中。 整個框架負責任務的排程和監控,以及重新執行已經失敗的任務。
通常,Map/Reduce框架和分散式檔案系統是執行在一組相同的節點上的,也就是說,計算節點和儲存節點通常在一起。這種配置允許框架在那些已經存好資料的節點上高效地排程任務,這可以使整個叢集的網路頻寬被非常高效地利用。
Map/Reduce框架由一個單獨的master JobTracker 和每個叢集節點一個slave TaskTracker共同組成。master負責排程構成一個作業的所有任務,這些任務分佈在不同的slave上,master監控它們的執行,重新執行已經失敗的任務。而slave僅負責執行由master指派的任務。
應用程式至少應該指明輸入/輸出的位置(路徑),並通過實現合適的介面或抽象類提供map和reduce函式。再加上其他作業的引數,就構成了作業配置(job configuration)。然後,Hadoop的 job client提交作業(jar包/可執行程式等)和配置資訊給JobTracker,後者負責分發這些軟體和配置資訊給slave、排程任務並監控它們的執行,同時提供狀態和診斷資訊給job-client。
雖然Hadoop框架是用Java實現的,但Map/Reduce應用程式則不一定要用 Java來寫 。
2.樣例分析:單詞計數
1、WordCount原始碼分析
單詞計數是最簡單也是最能體現MapReduce思想的程式之一,該程式完整的程式碼可以在Hadoop安裝包的src/examples目錄下找到
單詞計數主要完成的功能是:統計一系列文字檔案中每個單詞出現的次數,如圖所示:
(1)Map過程
Map過程需要繼承org.apache.hadoop.mapreduce包中的Mapper類,並重寫map方法
通過在map方法中新增兩句把key值和value值輸出到控制檯的程式碼,可以發現map方法中的value值儲存的是文字檔案中的一行(以回車符作為行結束標記),而key值為該行的首字元相對於文字檔案的首地址的偏移量。然後StringTokenizer類將每一行拆分成一個個的單詞,並將<word,1>作為map方法的結果輸出,其餘的工作都交由MapReduce框架處理。其中IntWritable和Text類是Hadoop對int和string類的封裝,這些類能夠被序列化,以方便在分散式環境中進行資料交換。
TokenizerMapper的實現程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public
static
class
TokenizerMapper extends
Mapper<Object, Text, Text, IntWritable>{
private
final
static
IntWritable one = new
IntWritable( 1 );
private
Text word = new
Text();
public
void
map(Object key, Text value, Context context) throws
IOException, InterruptedException {
System.out.println( "key
= "
+ key.toString()); //新增檢視key值
System.out.println( "value
= "
+ value.toString()); //新增檢視value值
StringTokenizer
itr = new
StringTokenizer(value.toString());
while
(itr.hasMoreTokens()) {
word.set(itr.nextToken());
context.write(word,
one);
}
}
}
|
(2)Reduce過程
Reduce過程需要繼承org.apache.hadoop.mapreduce包中的Reducer類,並重寫reduce方法
reduce方法的輸入引數key為單個單詞,而values是由各Mapper上對應單詞的計數值所組成的列表,所以只要遍歷values並求和,即可得到某個單詞的出現總次數
IntSumReduce類的實現程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 |
public
static
class
IntSumReducer extends
Reducer<Text,IntWritable,Text,IntWritable> {
private
IntWritable result =
|