我想对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 []
查看toDebugString
和spark UI,如果我理解的话,为了执行连接,DAG会查看应该使用的分区器,因为两个rdd都是HashPartitioned
,所以选择分区数较多的分区程序,rdd
partitioner。
现在,从火花用户界面开始,rdd
partitionBy
和join
似乎在同一个阶段执行,因此在这种情况下,需要进行随机播放加入,将从一边完成?从一方面来说,我的意思是只有rdd1将被洗牌,而不是两者。
我的假设是否正确?
答案 0 :(得分:2)
你是对的。如果使用不同的分区器对两个RDD进行分区,则Spark将选择一个作为引用,并仅选择第二个进行修复/混洗。
如果两者都有相同的分区,则不需要随机播放。