共同分区的 RDD 的加入是不是会导致 Apache Spark 中的洗牌?

Posted

技术标签:

【中文标题】共同分区的 RDD 的加入是不是会导致 Apache Spark 中的洗牌?【英文标题】:Does a join of co-partitioned RDDs cause a shuffle in Apache Spark?共同分区的 RDD 的加入是否会导致 Apache Spark 中的洗牌? 【发布时间】:2015-04-08 08:13:45 【问题描述】:

如果rdd1rdd2 具有相同的分区器,rdd1.join(rdd2) 会导致洗牌吗?

【问题讨论】:

你能改写这个问题更清楚吗?仅仅因为 RDD 在同一台机器上有分区并不意味着所有的键总是在同一分区上。那你在问什么? 我已经完全重写了这个问题。我认为现在有道理,但我不确定这是@zwb 的意思。原来我真的没看懂。如有必要,请随时恢复我的编辑并更新问题。 谢谢,我来自中国,我的英语很差,我表达的不是很清楚,你重写的是我的感觉。 【参考方案1】:

没有。如果两个 RDD 有相同的分区器,join 不会引起洗牌。你可以在CoGroupedRDD.scala看到这个:

override def getDependencies: Seq[Dependency[_]] = 
  rdds.map  rdd: RDD[_ <: Product2[K, _]] =>
    if (rdd.partitioner == Some(part)) 
      logDebug("Adding one-to-one dependency with " + rdd)
      new OneToOneDependency(rdd)
     else 
      logDebug("Adding shuffle dependency with " + rdd)
      new ShuffleDependency[K, Any, CoGroupCombiner](rdd, part, serializer)
    
  

但是请注意,没有随机播放并不意味着不必在节点之间移动任何数据。两个 RDD 可能具有相同的分区器(共同分区),但相应的分区位于不同的节点上(不位于同一位置)。

这种情况仍然比洗牌要好,但要记住这一点。托管可以提高性能,但很难保证。

【讨论】:

再次感谢,我基本上不明白,我会阅读源代码以获取更多信息。 后续问题:是否有任何利用共同分区的 Spark SQL 实现(包括不在主发行版中的单独项目)? @DanielDarabos,当您说:没有随机播放并不意味着不必在节点之间移动数据时,性能方面的差异究竟是什么。如果我理解的很好,RDDs co-partitioned 具有位于不同节点上的相应分区,将导致其中一个 RDD 的所有分区被移动到另一个 RDD 的相应分区所在的节点,对吗?毕竟所有的数据移动都可以被认为是洗牌? 当然,如果你自己定义了“shuffle”的含义,你总是可以这样定义,这样当加入共同分区的 RDD 时发生的就是一个“shuffle”。但是这个词在Spark内部其实是有定义的,答案就用这个定义。加入共同分区的 RDD 时不会发生 shuffle。 重新分区是一个洗牌:所有执行者复制到所有其他执行者。重定位是一对一的依赖关系:每个 executor 最多只能从另一个 executor 复制。在你的情况下,你可以通过基准测试找到它的速度有多快。确保托管的一种方法是让两个 RDD 派生自一个共同的祖先。

以上是关于共同分区的 RDD 的加入是不是会导致 Apache Spark 中的洗牌?的主要内容,如果未能解决你的问题,请参考以下文章

Spark - RDD 的分区和Shuffle

Spark RDD 默认分区数量 - repartitions和coalesce异同

加入两个产生空数据的 RDD

spark rdd--分区理解

spark中的RDD是啥

Spark中repartition和coalesce的用法