Spark_8 Spark常用算子對比

map與mapPartitions

map詳解:
Return a new RDD by applying a function to all elements of this RDD
對RDD中的每一個元素都執行一個function

mapPartitions:
Return a new RDD by applying a function to each partition of this RDD
RDD由n個Partition構成,每個Partition由m條數據構成
map是將函數作用到每一個元素上
而mapPartitions是將函數作用到每一個分區上

如果RDD 10Partitions,每個Par存儲100w
map:1000w次 connection
mapPartitions 10次 connection

但是Map也是有優勢的:
普通的map操作,這一堆操作是處理那一條記錄的數據(那一個元素的)
處理完之後,內存裏就清掉了,空間就騰出來了。所以map一般不會涉及到OOM的
但是MapPartitions不一樣,每次處理一個分區的數據,這個分區的數據處理完後,原 RDD 中分區的數據才能釋放。這種情況可能導致 OOM 。如果一個分區數據太多,內存扛不住了,直接就死掉了

第一選擇是MapPartitions,如果出現OOM,再考慮Map
foreach與foreachPartition同理:
在寫數據到外部數據庫時,優先使用foreachPartition

coalesce與repartition

coalesce 重新分區,可以選擇是否進行 shuffle 過程。默認將RDD的分區數減少到指定的分區數,不能放大,多的分區數變成少的分區數,不需要數據的shuffle;如果要放大 需要將第二個參數變成true。
由於分區數決定了之後產生的文件的個數,用於合併小文件(不shuffle,從多變少)
常用於和filter算子做配合,filter過濾之後使用coalesce來減少分區。

repartition 底層是調用coalesce(num,true),能夠增加或者減少分區,是肯定要進行shuffle的。
repartition用來打散數據,提高並行度,處理數據傾斜

reduceByKey與groupByKey

reduceByKey:
	sc.textFile("").flatMap(_.split("\t")).map((_,1)).reduceByKey(_+_).collect
groupByKey:
	sc.textFile("").flatMap(_.split("\t")).map((_,1)).groupByKey().map(x=>(x._1,x._2.sum)).collect

reduceByKey不僅簡單,shuffle的數據還比groupByKey的shuffle的數據少:
原因是reduceByKey 事先在map端本地做了一次聚合操作(combiner),combiner的結果再做了shuffle,所以shuffle的數據量少一些
所以工作當中優先使用reduceByKey

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章