中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

spark2.x由淺入深深到底系列六之RDD api reduceByKey與foldByKey對比

發布時間:2020-05-31 01:54:26 來源:網絡 閱讀:2601 作者:tangweiqun 欄目:大數據

學習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原理詳解

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

建平县| 濮阳县| 杭州市| 威宁| 讷河市| 绥中县| 和硕县| 乌恰县| 措美县| 潢川县| 盐山县| 富顺县| 南开区| 新宁县| 霍城县| 汪清县| 甘谷县| 赞皇县| 苏州市| 宁化县| 恩施市| 新干县| 盘山县| 阿拉善左旗| 西充县| 大新县| 福安市| 朝阳市| 永寿县| 弥勒县| 宜州市| 太仓市| 呈贡县| 九江市| 巩留县| 广水市| 高尔夫| 鄂州市| 沙雅县| 绍兴市| 崇州市|