- 笛卡尔积会产生shuffle吗?
- 有关窄依赖解惑
- 最后送一道面试题
1、笛卡尔积会产生shuffle吗?
结论是:不会
如果从网上搜的话,排在前几的答案,基本都是这样:
但是仔细分析笛卡尔积源码,就会发现,它的运行原理是这样的:
代码语言:javascript复制select tmp1.a,tmp2.b from testdata2 tmp1 join testdata2 tmp2
== executedPlan ==
CartesianProduct
:- SerializeFromObject [knownnotnull(assertnotnull(input[0, org.apache.spark.sql.test.SQLTestData$TestData2, true])).a AS a#3]
: - Scan[obj#2]
- SerializeFromObject [knownnotnull(assertnotnull(input[0, org.apache.spark.sql.test.SQLTestData$TestData2, true])).b AS b#12]
- Scan[obj#10]
笛卡尔积的分片方法:
getDependencies方法:
整个过程在map端执行,没有shuffle
2、有关窄依赖
这个如果在百度上搜相关内容,大部分都这么定义:
如果这样理解的话,就会很矛盾,笛卡尔积的依赖中,一个父RDD的分区明明被多个子RDD的分区消费了,可它是窄依赖
我们看窄依赖的源码:
代码语言:javascript复制**
* :: DeveloperApi ::
* Base class for dependencies where each partition of the child RDD depends on a small number
* of partitions of the parent RDD. Narrow dependencies allow for pipelined execution. *
*/
@DeveloperApi
abstract class NarrowDependency[T](_rdd: RDD[T]) extends Dependency[T] {
/**
* Get the parent partitions for a child partition.
* @param partitionId a partition of the child RDD
* @return the partitions of the parent RDD that the child partition depends upon
*/
def getParents(partitionId: Int): Seq[Int]
override def rdd: RDD[T] = _rdd
}
从这个注释上来看,应该这么翻译:其中子RDD的每个分区依赖于父RDD的小部分区
后来,我就想网上的说法是怎么来的呢?
翻了之前版本的源码,发现了出处:
spark1.0版本的窄依赖注释:其中父RDD的每个分区最多由子RDD的一个分区使用
所以,我想,恐怕现在网上流行的都是spark1.0版本的窄依赖定义,现在已经进化到spark3了,应该以最新来
3、给一道面试题吧
join一定会发生shuffle吗?
不一定,下面这些情况下join不会产生shuffle
- 笛卡尔积
- BroadcastHashJoin
- BroadcastNestedLoopJoin
- 使用相同的分区器进行一次分区然后再去join,这时join不会发生shuffle
没有特别标准的答案,重要的是多积累,把自己平时遇到的,学到的一点点积累下来,慢慢的就变成了自己的底蕴