spark rdd實戰—分區器(Partitioner)的理解和使用

概述

《spark2原理分析-RDD的Partitioner原理分析》一文中,我們瞭解了分區器的基本概念,本文通過實際的例子來進一步理解分區器的概念,並學習如何使用分區器。

分區器的使用場景

分區器在類型爲(k,v)的RDD時使用。但不要頻繁的修改分區器,頻繁使用分區器可能會導致更多的shuffle操作。

HashPartitioner分區器的使用

  • 準備類型爲(k,v)的RDD
    我們通過parallelize生成(k,v)對的RDD數據,在spark-shell中代碼如下:
scala> import org.apache.spark.HashPartitioner
scala> val rdd2 = sc.parallelize(1 to 10000).map(x=>(x,x))
rdd2: org.apache.spark.rdd.RDD[(Int, Int)] = MapPartitionsRDD[1] at map at <console>:24

scala> rdd2.partitions.length
res2: Int = 8

scala> rdd2.partitioner
res0: Option[org.apache.spark.Partitioner] = None

由於我是以local[*]模式啓動的,而我的機器有8個核,所以默認的分區數是8。但從以上代碼可以看出,分區器爲None。
下面我們使用新的分區器:HashPartitioner來對數據進行重新分區:

  • 使用HashPartitioner分區器重新分區
scala> val rdd3 = rdd2.partitionBy(new HashPartitioner(10))
rdd3: org.apache.spark.rdd.RDD[(Int, Int)] = ShuffledRDD[3] at partitionBy at <console>:26

scala> rdd3.partitioner
res9: Option[org.apache.spark.Partitioner] = Some(org.apache.spark.HashPartitioner@a)

scala> rdd3.partitions.length
res10: Int = 10

從以上例子中看出,我們使用自帶的HashPartitioner(10)分區器來重新分區數據,重新定義分區器後,分區數已經發生了變化。分區數變成了按HashPartitioner分區的分區數。

RangePartitioner分區器的使用

  • 使用RangePartitioner分區器重新分區
scala> import org.apache.spark.RangePartitioner
import org.apache.spark.RangePartitioner

scala> val rdd3 = rdd2.partitionBy(new RangePartitioner(20, rdd2))
rdd3: org.apache.spark.rdd.RDD[(Int, Int)] = ShuffledRDD[4] at partitionBy at <console>:26

scala> rdd3.partitioner
res3: Option[org.apache.spark.Partitioner] = Some(org.apache.spark.RangePartitioner@49057ee6)

scala> rdd3.partitions.length
res4: Int = 20

從以上的代碼例子中可以看出,設置RangePartitioner分區器後,分區數變成了20個。

打印每個分區的數據

val parts = rdd3.partitions
for (p <- parts) {
    val idx = p.index
    val partRdd = rdd3.mapPartitionsWithIndex { 
       case(index:Int,value:Iterator[(String,Int)]) => 
         if (index == idx) value else Iterator()
    }
    val dataPartitioned = partRdd.collect()
    println("partition id:"+ idx, "elements: " + dataPartitioned.foreach(print))
}

通過這段代碼可以打印出每個分區的數據。
通過打印RangePartitioner重新分區後的數據可以看出,RangePartitioner分區後的數據基本上是按照數據範圍來劃分的。

小結

本文說明了分區器的使用。並通過修改分區器來驗證了分區器的作用。

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