影響Spark輸出RDD分區的操作函數

1. 會影響到Spark輸出RDD分區(partitioner)的操作

cogroup, groupWith, join, leftOuterJoin, rightOuterJoin, groupByKey, reduceByKey, combineByKey, partitionBy, sort, mapValues(如果父RDD存在partitioner), flatMapValues(如果父RDD存在partitioner), 和 filter (如果父RDD存在partitioner)。


2. 不會影響輸出RDDpartitioner

其他的transform操作不會影響到輸出RDD的partitioner,一般來說是None,也就是沒有partitioner。

下面舉個例子進行說明:

scala> val pairs = sc.parallelize(List((1, 1), (2, 2), (3, 3)))
    pairs: org.apache.spark.rdd.RDD[(Int, Int)] = 
    ParallelCollectionRDD[4] at parallelize at <console>:12

scala> val a = sc.parallelize(List(2,51,2,7,3))
    a: org.apache.spark.rdd.RDD[Int] = 
    ParallelCollectionRDD[5] at parallelize at <console>:12

scala> val a = sc.parallelize(List(2,51,2))
    a: org.apache.spark.rdd.RDD[Int] = 
    ParallelCollectionRDD[6] at parallelize at <console>:12

scala> val b = sc.parallelize(List(3,1,4))
    b: org.apache.spark.rdd.RDD[Int] =
    ParallelCollectionRDD[7] at parallelize at <console>:12

scala> val c = a.zip(b)
    c: org.apache.spark.rdd.RDD[(Int, Int)] = 
    ZippedPartitionsRDD2[8] at zip at <console>:16

scala> val result = pairs.join(c)
    result: org.apache.spark.rdd.RDD[(Int, (Int, Int))] = 
    FlatMappedValuesRDD[11] at join at <console>:20

scala> result.partitioner
    res6: Option[org.apache.spark.Partitioner] = Some(org.apache.spark.HashPartitioner@2)

大家可以看到輸出來的RDD result分區變成了HashPartitioner,因爲join中的兩個分區都沒有設置分區,所以默認用到了HashPartitioner,可以看join的實現:

def join[W](other: RDD[(K, W)]): RDD[(K, (V, W))] = {
    join(other, defaultPartitioner(self, other))
}

def defaultPartitioner(rdd: RDD[_], others: RDD[_]*): Partitioner = {
    val bySize = (Seq(rdd) ++ others).sortBy(_.partitions.size).reverse
    for (r <- bySize if r.partitioner.isDefined) {
      return r.partitioner.get
    }
    if (rdd.context.conf.contains("spark.default.parallelism")) {
      new HashPartitioner(rdd.context.defaultParallelism)
    } else {
      new HashPartitioner(bySize.head.partitions.size)
    }
}

defaultPartitioner函數就確定了結果RDD的分區。從上面的實現可以看到,
  1、join的兩個RDD如果都沒有partitioner,那麼join結果RDD將使用HashPartitioner
  2、如果兩個RDD中其中有一個有partitioner,那麼join結果RDD將使用那個父RDD的partitioner
  3、如果兩個RDD都有partitioner,那麼join結果RDD就使用調用join的那個RDD的partitioner
  


【完】

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