一、作用
1、combiner最基本是實現本地key的聚合,對map輸出的key排序,value進行迭代。如下所示:
map: (K1, V1) → list(K2, V2)
combine: (K2, list(V2)) → list(K2, V2)
reduce: (K2, list(V2)) → list(K3, V3)
2、combiner還具有類似本地的reduce功能.
例如hadoop自帶的wordcount的例子和找出value的最大值的程序,combiner和reduce完全一致。如下所示:
map: (K1, V1) → list(K2, V2)
combine: (K2, list(V2)) → list(K3, V3)
reduce: (K3, list(V3)) → list(K4, V4)
3、如果不用combiner,那么,所有的結果都是reduce完成,效率會相對低下。使用combiner,先完成的map會在本地聚合,提升速度。
4、對於hadoop自帶的wordcount的例子,value就是一個疊加的數字,所以map一結束就可以進行reduce的value疊加,而不必要等到所有的map結束再去進行reduce的value疊加。
二、總結
1、combiner使用的合適,可以在滿足業務的情況下提升job的速度,如果不合適,則將導致輸出的結果不正確。
每一個map都可能會產生大量的本地輸出,Combiner的作用就是對map端的輸出先做一次合並,以減少在map和reduce節點之間的數據傳輸量,以提高網絡IO性能,是MapReduce的一種優化手段之一。
1)、Combiner最基本是實現本地key的聚合,對map輸出的key排序、value進行迭代。如下所示:
map:(key1,value1) ——> list(key2,value2)
conbine:(key2,list(value2)) ——> list(key2,value2)
reduce:(key2,list(value2)) ——> list(key3,value3)
2)、Combiner還有本地reduce功能(其本質上就是一個reduce):
map:(key1,value1) ——> list(key2,value2)
conbine:(key2,list(value2)) ——> list(key3,value3)
reduce:(key3,list(value3)) ——> list(key4,value4)
3)、如果不用Combiner,南無說有的結果都會在reduce端完成,效率比較低小,並且會占用很多的網絡IO;使用Combiner先完成在map端的本地聚合,可以減少網絡傳輸數據量,提高性能。
但是,不要以為在寫MapReduce程序時設置了Combiner就認為Combiner一定會起作用,實際情況是這樣的嗎?答案是否定的。hadoop文檔中也有說明Combiner可能被執行也可能不被執行。那么在什么情況下不執行呢?如果當前集群在很繁忙的情況下job就是設置了也不會執行Combiner。
另外還要注意,Combiner使用的合適的話會提高Job作業的執行數度,但是使用不合適的話,會導致輸出的結果不正確。Combiner的輸出是Reduce的輸入,它絕不會改變最終的計算結果。
Conbiner的適用場景比如說在匯總統計時,就可以使用Conbiner,但是在求平均數的時候就是適合適用了。
最后,我們再來看一下Combiner的執行時機。我們之前已對map端的shuffle做過比較升入的了解,詳情請看MapTask詳解。那么,Combiner會在map端的那個時期執行呢?實際上,Conbiner函數的執行時機可能會在map的merge操作完成之前,也可能在merge之后執行,這個時機由配置參數min.num.spill.for.combine(該值默認為3),也就是說在map端產生的spill文件最少有min.num.spill.for.combine的時候,Conbiner函數會在merge操作合並最終的本機結果文件之前執行,否則在merge之后執行。通過這種方式,就可以在spill文件很多並且需要做conbine的時候,減少寫入本地磁盤的數據量,同樣也減少了對磁盤的讀寫頻率,可以起到優化作業的目的。
參考:http://blog.csdn.net/ipolaris/article/details/8723782
http://blog.csdn.net/cnbird2008/article/details/23788233
http://hadoop.apache.org/docs/r1.2.1/streaming.html#Hadoop+Streaming