您好,登錄后才能下訂單哦!
學習spark任何知識點之前,最好先正確理解spark,可以參考:正確理解spark
一、序言
對于key-value類型RDD的兩個api, reduceByKey與foldByKey,我們往往只是簡單的知道它們不同的點就是foldByKey比reduceByKey多了一個初始值,但是僅僅知道這么一點是完全不夠的,我們還是不知道怎么合理的去用這兩個api,所以有必要對兩個api做一個詳細的對比。我們接下來先從RDD的另外兩個action api reduce和fold入手,然后慢慢的分析reduceByKey與foldByKey使用場景
二、RDD action Api -- reduce 和 fold
我們從如下兩個方面來對比這兩個api
1、分別對空的RDD應用這兩個Api,如下:
//創建一個空的RDD val emptyRdd = sc.emptyRDD[Int] //對空的RDD進行reduce會報如下錯 //java.lang.UnsupportedOperationException: empty collection // at org.apache.spark.rdd.RDD$$anonfun$reduce$1$$anonfun$apply$36.apply(RDD.scala:1027) emptyRdd.reduce(_ + _) //對空的RDD進行fold則不會,而是返回0 emptyRdd.fold(0)(_ + _) // res1: Int = 0
2、從產生臨時對象的多少來區別這兩個api
//創建一個RDD,RDD的類型為ArrayBuffer val testRdds = sc.parallelize(Seq(ArrayBuffer(0, 1, 3), ArrayBuffer(2, 4, 5))) //對testRdds進行reduce,如下: //會產生很多的中間臨時對象 因為ArrayBuffer ++ ArrayBuffer會創建一個新的ArrayBuffer對象 testRdds.reduce(_ ++ _) //對testRdds進行fold,如下: // ArrayBuffer只初始化一次,每次都是將ArrayBuffer append到之前的ArrayBuffer中,不會產生中間臨時對象 testRdds.fold(ArrayBuffer.empty[Int])((buff, elem) => buff ++= elem)
從上面可以看出,fold操作將會產生很少的中間對象,如果中間對象太多了的話,則會導致gc頻繁,進而影響性能,所以使用reduce和fold的時候,我們需要考慮下會不會產生很多的臨時對象,如果會的話,我們能不能使用fold操作來避免產生過多的中間對象
三、key-value類型RDD api -- reduceByKey與foldByKey
我們也是從如下兩個方面來考慮:
1、對空的RDD應用這兩個Api,行為是一致的,都是返回0
val emptyKeyValueRdd = sc.emptyRDD[(Int, Int)] emptyKeyValueRdd.reduceByKey(_ + _).collect //0 emptyKeyValueRdd.foldByKey((0))(_ + _).collect //0
2、從產生臨時對象的多少來區別這兩個api
//構建一個key-value類型的RDD val testPairRdds = sc.parallelize(Seq(("key1", ArrayBuffer(0, 1, 3)), ("key2", ArrayBuffer(2, 4, 5)), ("key1", ArrayBuffer(2, 1, 3)))) //對testPairRdds應用reduceByKey, 如果相同的key的數據特別多的話,也會產生特別多的臨時對象,因為ArrayBuffer ++ ArrayBuffer會創建一個新的ArrayBuffer對象 testPairRdds.reduceByKey(_ ++ _).collect() //對testPairRdds應用foldByKey,對每一個key來說,ArrayBuffer只初始化一次,每次都是將ArrayBuffer append到之前的ArrayBuffer中,不會產生中間臨時對象 testPairRdds.foldByKey(ArrayBuffer.empty[Int])((buff, elem) => buff ++= elem).collect()
從上面也可以看出,foldByKey與reduceByKey的應用場景其實和fold與reduce是一樣的,所以對于中間臨時對象產生的情況下,我們需要在foldByKey與reduceByKey兩者中選擇好
對于RDD其他的api的原理及其使用的時候需要注意的點,可以參考:spark core RDD api原理詳解
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。