连接的RDD上的随机分区程序行为

时间:2016-02-19 15:25:52

标签: scala apache-spark

我正在尝试加入两个数据集。其中一种类型(Id,salesRecord)另一种(Id,Name)。 第一个数据集由HashPartitioner分区,第二个数据集由Custom Partitioner分区。当我通过id加入这些RDD并尝试查看保留哪个分区信息时,我随机看到有时候joinRDD会显示自定义分区器,有时候会显示HashPartitioner。我在改变分区数量的同时收到了不同的分区结果。

根据Learning Spark一书,rdd1.join(rdd2)保留了rdd1的分区信息。

这是代码。

  val hashPartitionedRDD = cusotmerIDSalesRecord.partitionBy(new HashPartitioner(10))
println("hashPartitionedRDD's partitioner " + hashPartitionedRDD.partitioner) // Seeing Instance of HashParitioner

val customPartitionedRDD = customerIdNamePair1.partitionBy(new CustomerPartitioner)
println("customPartitionedRDD partitioner " + customPartitionedRDD.partitioner) // Seeing instance of CustomPartitioner

val expectedHash = hashPartitionedRDD.join(customPartitionedRDD)
val expectedCustom = customPartitionedRDD.join(hashPartitionedRDD)

println("Expected Hash " + expectedHash.partitioner) // Seeing instance of Custom Partitioner
println("Expected Custom " + expectedCustom.partitioner) //Seeing instance of Custom Partitioner

// Just to add more to it when number of partitions of both the data sets I made equal I am seeing the reverse results. i.e. 
// expectedHash shows CustomPartitioner and 
// expectedCustom shows Hashpartitioner Instance.

1 个答案:

答案 0 :(得分:4)

join方法内部调用Partitioner.defaultPartitioner()方法。

基于defaultPartitioner

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

如果仔细观察:

val bySize = (Seq(rdd) ++ others).sortBy(_.partitions.size).reverse

它以降序的顺序启动for-loop(或搜索)。因此,如果RDDs都有自己的分区程序,则会选择分区数较多的

编辑:您提出的有关查看reverse行为的问题非常简单。在这里,如果两个分区具有相同数量的分区,则others将位于Seq的顶部。因此,将选择参数RDD的分区器。

(Seq(rdd) ++ others).sortBy(_.partitions.size).reverse

这种行为是可以解释的,但可能不直观。