MapReducer中的多次歸約處理

Thinkgamer_gyt發表於2015-07-28

我們知道,MapReduce是分為Mapper任務和Reducer任務,Mapper任務的輸出,通過網路傳輸到Reducer任務端,作為輸入。

在Reducer任務中,通常做的事情是對資料進行歸約處理。既然資料來源是Mapper任務的輸出,那麼是否可以在Mapper端對資料進行歸約處理,業務邏輯與Reducer端做的完全相同。處理後的資料再傳送到Reducer端,再做一次歸約。這樣的好處是減少了網路傳輸的數量。

可能有人疑惑幾個問題:

為什麼需要在Mapper端進行歸約處理?

為什麼可以在Mapper端進行歸約處理?

既然在Mapper端可以進行歸約處理,為什麼在Reducer端還要處理?

回答第一個問題:因為在Mapper進行歸約後,資料量變小了,這樣再通過網路傳輸時,傳輸時間就變短了,減少了整個作業的執行時間。

回答第二個問題:因為Reducer端接收的資料就是來自於Mapper端。我們在Mapper進行歸約處理,無非就是把歸約操作提前到Mapper端做而已。

回答第三個問題:因為Mapper端的資料僅僅是本節點處理的資料,而Reducer端處理的資料是來自於多個Mapper任務的輸出。因此在Mapper不能歸約的資料,在Reducer端有可能歸約處理。

在Mapper進行歸約的類稱為Combiner。那麼,怎麼寫Combiner哪?非常簡單,就是我們自定義的Reducer類。那麼,怎麼用哪?更簡單,見如下程式碼


job.setCombineClass(Mapper.class)

要注意的是,Combiner只在Mapper任務所在的節點執行,不會跨Mapper任務執行。Reduce端接收所有Mapper端的輸出來作為輸入。雖然兩邊的歸約類是同一個,但是執行的位置完全不一樣。

並不是所有的歸約工作都可以使用Combiner來做。比如求平均值就不能使用Combiner。因為對於平均數的歸約演算法不能多次呼叫。

相關文章