开发者学堂课程【大数据 Spark 2020版(知识精讲与实战演练)第三阶段:Spark 原理_逻辑图_窄依赖_分析】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/689/detail/12015
Spark 原理_逻辑图_窄依赖_分析
内容简介
一、明确步骤
二、分析笛卡尔积案例
三、总结
一、明确步骤
1.Spark 原理中很重要一个部分是逻辑执行图,逻辑执行图就是 RDD 的生成和 RDD 之间的关系,RDD 之间的关系,大致分为两种:窄依赖和宽依赖。
2.窄依赖
(1)求笛卡尔积
上节所编写的案例
(2)分析案例是否是窄依赖
//这样就需要一个标准来判断宽窄依赖
3.区分宽窄依赖的原因
想要看看 RDD 的分区是否能放在同一个流水线上执行,能否放在一个流水线上执行?取决于这两个 RDD 之间是否是 Shuffle 关系,有 Shuffle 是窄依赖,反之就是宽依赖
//如果有 shuffle 关系,就不能放在一个流水线上执行
二、分析笛卡尔积案例
1.案例分析
案例如下:
Val sc = ....
Val rddA = sc.parallelize(Seq(1,2,3,))
Val rddB = sc.parallelize(Seq(
“a”,”b”))
/**
*运行结果:(1,a),(1,b), (2,a), (2,b),(3,a),(3,b)
*/
rddA.cartesian(rddB).collect().foreach(printin(_))
# rddA 和 rddB 生成的为 rddC
其实创建笛卡尔积就是创建两个分区、rddaA 和 rddB,一个存放1、2、3,一个存放 a、b
求笛卡尔积就是将 rddA 中的每个元素和 rddB 中的每个元素进行整合连接
分辨 rddA 和 rddB 与 rddC 之间的关系
上述代码的 cartesian 是求得两个集合的笛卡尔积
上述代码的运行结果是 rddA 中每个元素和 rddB 中的所有元素结合,最终的结果数量是两个 RDD 数量之和
RddC 有两个父 RDD,分别为 rddA 和 rddB
对于 cartesian 来说,依赖关系如下:
假设 rddA 和 rddB 中的每个分区中只有一条数据,rddA 的p1、p2、p3 中的内容分别是1、2、3;rddB 的 p1、p2 对应的内容是:a、b
则 rddC 中从 p1~p6 中的数据分别为 1a,1b,2a,2b,3a,3b
中间关系是否是 shuffle?
RddC 的 p1 依赖了两个分区,rddA 的 p1 和 rddB 的 p1
如何判断宽窄依赖/如何判断是否含有 shuffle ?
如果含有 shuffle ,则分区中的数据还要进行拆分,例如 p1 分区,其中的数据将要进行拆分,并不会全部转入 rddC,其中 rdd 的 p1 中的数据是没有再分的,没有分区,shuffle 会对数据进行分区,所以这里属于窄依赖。
//第一个分区(rddA)会发个第一个结果分区(rddC),第二个分区会发个第二个结果分区,这样被称为 shuffle
这里没有明确的说一定是款窄依赖,是否含有 shuffle,所以我们要从源码中进行研究
2.举例
进入编码
点击 cartesian 算子
进入后,会发现生成的是 cartesianRDD
继续点击 cartesianRDD,可以看到 getdependency 分区中,返回的都是 narrowdependency//叫做窄依赖 ,点进
# rdd 当中有三个必要属性:分区列表、依赖关系、计算函数
可以进入到一个 dependency 的文件中,shuffledependency 代表宽依赖
所以只需要进入 cortesianRDD 中查看返回的 dependency 类型就可以判断宽窄依赖
三、总结
所有的分区之间是拷贝关系,并不是 shuffle 关系
// rddA p1 将数据放入 rddC p1 中,称为拷贝关系并不准确,方便理解,这里这样称呼
RddA P1 并没有被拆开分发给 rddC 的多个分区,所以它们之间并不是 shuffle 关系
1.Rdd 中的每个分区并不是依赖多个父 RDD 中的多个分区
2.RddC 中每个分区的数量来自一个父 RDD 分区中的所有数据,是一个 fulldependence,所以数据可以直接从父 RDD 流动到子 RDD
3.不存在一个父 RDD 中一部分数据分发过去,另一部分分发给其他的 rdd