spark-運算元-分割槽運算元

zdkdchao發表於2020-11-05

partitionBy

在這裡插入圖片描述

val inputRDD = sc.parallelize(Array[(Int,Char)] ((1, 'a'),(2,'b'),(3,'C') (4,'d'),(2,'e'),(3,'f'),(2,'g'),(1, 'h')),3)

val resultRDD = inputRDD.partitionBy(new HashPartitioner (2))//使用HashPartitioner重新分割槽
val resultRDD = inputRDD.partitionBy(new RangePartitioner(2,inputRDD))//使用RangePartitioner重新分割槽

同repartition區別,partitionBy是根據partitioner,而repartition是隨機策略,不能指定partitioner

coalesce

用來改變分割槽數,根據隨機生成的key,使用隨機策略均勻的分佈資料,只能傳入分割槽數,不能指定partitioner

val sc = new SparkContext()
val inputRDD = sc.parallelize(Array[(Int, Char)]((3, 'c'), (3, 'f'), (1, 'a'), (4, 'd'), (1, 'h'), (2, 'b'), (5, 'e'), (2, 'g')), 5)
var coalesceRDD = inputRDD.coalesce(2) //圖3.19中的第1個圖
coalesceRDD = inputRDD.coalesce(6) //圖3.19中的第2個圖
coalesceRDD = inputRDD.coalesce(2, true) // 圖3.19中的第3個圖
coalesceRDD = inputRDD.coalesce(6, true) //圖3.19中的第4個圖
  1. 減少分割槽個數
    在這裡插入圖片描述
    如圖319中的第1個圖所示,rdd1的分割槽個數為5,當使用coalesce(2)減少為兩個分割槽時,spark會將相鄰的分割槽直接合並在一起,得到rdd2,形成的資料依賴關係是多對一的NarrowDependency.這種方法的缺點是,當rdd1中不同分割槽中的資料量差別較大時,直接合並容易造成資料傾斜(rdd2中某些分割槽資料量過多或過少)
  2. 增加分割槽個數
    在這裡插入圖片描述
    如圖3.19中的第2個圖所示,當使用coalesce(6)將rdd1的分割槽個數增加為6時,會發現生成的rdd2的分割槽個數並沒有增加,還是5。這是因為coalesce()預設使用NarrowDependency,不能將一個分割槽拆分為多份。
  3. 使用Shuffle來減少分割槽個數:
    在這裡插入圖片描述
    如圖3.19中的第3個圖所示,為了解決資料傾斜的問題,我們可以使用coalesce(2, Shuffle = true)來減少RDD的分割槽個數。使用Shuffle = true後,Spark 隨機將資料打亂,從而使得生成的RDD中每個分割槽中的資料比較均衡。具體採用的方法是為rdd1中的每個record新增一個特殊的Key,如第3個圖中的MapPartitionsRDD,Key是 Int型別,並從[0, numPartitions)中隨機生成,如<3,f >=><2,(3,f)>中,2是隨機生成的Key,接下來的record的Key遞增1,如<1,a> =><3,(1,a)>。這樣,Spark可以根據Key的 Hash值將rdd1中的資料分發到rdd2的不同的分割槽中,然後去掉Key即可(見最後的 MapPartitionsRDD)。
  4. 使用Shuffle來增加分割槽個數:
    在這裡插入圖片描述
    如圖3.19 中的第4個圖所示,通過使用ShuffeDepedency,可以對分割槽進行拆分和充足,解決分割槽個數不能增加的問題。

repartition = coalesce(numPartitions,true)

相關文章