Hadoop實例練習(一)

實現目標:


在對文檔進行單詞詞頻計算的同時,對輸出結果按單詞的詞頻進行排序



設計思路:


用一個並行計算任務顯然是無法同時完成單詞詞頻統計和排序的。爲什麼無法同時完成呢?

想一下單詞詞頻統計任務的MapReduce過程:

在Map階段,Mapper將作爲輸入的n個文檔分割爲對應的n(或n個以上)個InputSplits,每個InputSplits分配給一個Mapper--> 調用RecordReader將每個InputSplits的每行解析成一個<key,value>對,key爲行號,value爲每行的內容--> 調用用戶填寫的map()函數,對每個<key,value>進行處理(相當於對文檔中的每一行進行處理),把value轉換爲字符串,根據空格或其他字符進行切割,對每個切割好的單詞形成<key,value>對,key爲該單詞,value爲1,輸出到OutputCollector(Hadoop框架提供,專門用來負責收集Mapper和Reducer的輸出結果)中-->若定義了combiner,將該Mapper的所有結果按key值(即單詞)排序,把相同key值合併,作爲Mapper最終的輸出結果輸出;

Partition根據Mapper的輸出將所有key值相同的分配到一個Reducer;

Reducer階段:對接收到的數據排序,按key值排序--> 調用用戶輸入的reduce()函數,合併相同key值得value然後輸出。過程如下圖所示:

wKioL1ORHsqDZZxUAAFftmEcQYc442.jpg

上述過程中,在Mapper和Reducer階段都有按key值(單詞)排序的過程,所以在一個job中,要同時完成單詞詞頻統計和按value值排序輸出是不可能的,因爲排好序後還是會被Mapper和Reducer中的排序過程打亂。

疑問:Partition分配數據時,相同key值得分配到一個Reducer中,有沒大小限制?如果相同key值得數據很大很大呢?會不會分配到兩個Reducer?所有相同key值得分配到一個Reducer,但一個Reducer中也可能有其他不同key值的?否則實驗時得結果說不過去。



爲了實現目標,可以分爲兩個job順序執行,可以利用Hadoop的任務管道能力,用上一個任務(單詞詞頻統計任務)的輸出作爲下一個任務(排序)的輸入,順序執行兩個並行計算任務。

只需要利用Hadoop自身的排序過程既可以完成排序,問題是Hadoop是根據key值(單詞)進行排序的,而我們需要以詞頻次數,即value值進行排序,所以可以直接使用InverseMapper類,該類的任務就是簡單的將key和value值對調,所以只要在第二個job任務中將Mapper類設置爲InverseMapper(已經實現好的)即可:

sortJob.setMapperClass(InverseMapper.class);

無需指定Reducer類,Hadoop會使用默認的IdentityReducer類,直接輸出中間結果;


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章