Apache Spark DAG行为的cogrouped操作

时间:2017-03-23 11:46:32

标签: apache-spark rdd directed-acyclic-graphs

我想对DAG行为做一些澄清,以及如何处理以下工作:

val rdd = sc.parallelize(List(1 to 10).flatMap(x=>x).zipWithIndex,3)
.partitionBy(new HashPartitioner(4))

val rdd1 = sc.parallelize(List(1 to 10).flatMap(x=>x).zipWithIndex,2)
.partitionBy(new HashPartitioner(3))

val rdd2 = rdd.join(rdd1)
rdd2.collect()

这是相关的rdd2.toDebugString

(4) MapPartitionsRDD[6] at join at IntegrationStatusJob.scala:92 []
 |  MapPartitionsRDD[5] at join at IntegrationStatusJob.scala:92 []
 |  CoGroupedRDD[4] at join at IntegrationStatusJob.scala:92 []
 |  ShuffledRDD[1] at partitionBy at IntegrationStatusJob.scala:90 []
 +-(3) ParallelCollectionRDD[0] at parallelize at IntegrationStatusJob.scala:90 []
 +-(3) ShuffledRDD[3] at partitionBy at IntegrationStatusJob.scala:91 []
    +-(2) ParallelCollectionRDD[2] at parallelize at IntegrationStatusJob.scala:91 []

这是火花UI图片: enter image description here

查看toDebugString和spark UI,如果我理解的话,为了执行连接,DAG会查看应该使用的分区器,因为两个rdd都是HashPartitioned,所以选择分区数较多的分区程序,rdd partitioner。

现在,从火花用户界面开始,rdd partitionByjoin似乎在同一个阶段执行,因此在这种情况下,需要进行随机播放加入,将从一边完成?从一方面来说,我的意思是只有rdd1将被洗牌,而不是两者。

我的假设是否正确?

1 个答案:

答案 0 :(得分:2)

你是对的。如果使用不同的分区器对两个RDD进行分区,则Spark将选择一个作为引用,并仅选择第二个进行修复/混洗。

如果两者都有相同的分区,则不需要随机播放。