我正在尝试加入两个数据集。其中一种类型(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.
答案 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
这种行为是可以解释的,但可能不直观。