深入理解groupByKey、reduceByKey區別——本質就是一個local machine的reduce操作


下面來看看groupByKey和reduceByKey的區別:

    val conf = new SparkConf().setAppName("GroupAndReduce").setMaster("local") val sc = new SparkContext(conf) val words = Array("one", "two", "two", "three", "three", "three") val wordsRDD = sc.parallelize(words).map(word => (word, 1)) val wordsCountWithReduce = wordsRDD. reduceByKey(_ + _). collect(). foreach(println) val wordsCountWithGroup = wordsRDD. groupByKey(). map(w => (w._1, w._2.sum)). collect(). foreach(println)

雖然兩個函數都能得出正確的結果, 但reduceByKey函數更適合使用在大數據集上。 這是因為Spark知道它可以在每個分區移動數據之前將輸出數據與一個共用的key結合。

借助下圖可以理解在reduceByKey里發生了什么。 在數據對被搬移前,同一機器上同樣的key是怎樣被組合的( reduceByKey中的 lamdba 函數)。然后 lamdba 函數在每個分區上被再次調用來將所有值 reduce成最終結果。整個過程如下:


image

另一方面,當調用 groupByKey時,所有的鍵值對(key-value pair) 都會被移動,在網絡上傳輸這些數據非常沒必要,因此避免使用 GroupByKey。

為了確定將數據對移到哪個主機,Spark會對數據對的key調用一個分區算法。 當移動的數據量大於單台執行機器內存總量時Spark會把數據保存到磁盤上。 不過在保存時每次會處理一個key的數據,所以當單個 key 的鍵值對超過內存容量會存在內存溢出的異常。 這將會在之后發行的 Spark 版本中更加優雅地處理,這樣的工作還可以繼續完善。 盡管如此,仍應避免將數據保存到磁盤上,這會嚴重影響性能。


image

你可以想象一個非常大的數據集,在使用 reduceByKey 和 groupByKey 時他們的差別會被放大更多倍。

 

摘自:http://www.jianshu.com/p/0c6705724cff


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM