什么是 DAG(有向无环图)?它在 Spark 中的作用是什么?
这是一个非常经典的分布式计算面试题。简单来说,DAG 是 Spark 任务调度的核心逻辑。
以下是关于 DAG(有向无环图) 的详细解释及其在 Spark 中的作用:
1. 什么是 DAG?
DAG 是 Directed Acyclic Graph 的缩写,中文称为 有向无环图。它是一个图论中的概念,由顶点(Nodes)和边(Edges)组成。
我们可以拆解这三个词来理解:
- Graph(图):由节点和连接节点的线组成的结构。
- Directed(有向):连接线是有方向的(单行道),从一个节点指向另一个节点(例如 A B)。
- Acyclic(无环):图中不存在闭环。也就是说,你不能从一个点出发,顺着箭头走,最后又回到起点。流程必须是向前推进的。
生活中的类比:
这就好比做一道菜的流程图:
- 洗菜 切菜 炒菜 装盘。
- 这是一个有方向的流程,你不能在“装盘”之后又回到“洗菜”(无环),且必须按顺序进行(有向)。
2. DAG 在 Spark 中的具体形态
在 Spark 中,DAG 用来描述任务的执行逻辑:
- 节点(Nodes):代表 RDD(弹性分布式数据集)或 DataFrame。
- 边(Edges):代表对数据执行的 操作(Transformations),如
map、filter、reduceByKey等。
当你在 Spark 中写代码时(例如 rdd.map(...).filter(...)),Spark 并不会立即执行,而是会在后台画一张 DAG 图,记录下数据需要经过哪些步骤。
3. DAG 在 Spark 中的核心作用
DAG 是 Spark 区别于传统 Hadoop MapReduce 的关键优势之一。它的作用主要体现在以下三个方面:
A. 构建逻辑执行计划(Lazy Evaluation 的基础)
Spark 采用 惰性求值(Lazy Evaluation) 机制。
- 当你调用
map、filter等 Transformation 算子时,Spark 不会马上计算数据,而是将这些操作记录在 DAG 中。 - 只有当你调用
collect、save、count等 Action 算子时,Spark 才会将生成的 DAG 提交给 DAG Scheduler 开始真正的计算。 - 作用:这使得 Spark 拥有了“全局视野”,在计算开始前就能看到完整的处理流程。
B. 任务调度与优化(Stage 划分)
这是 DAG 最重要的作用。DAG Scheduler 会根据 DAG 图将整个作业(Job)切分成多个 阶段(Stages)。
- 宽依赖与窄依赖:
- 窄依赖(Narrow Dependency):父 RDD 的一个分区只被子 RDD 的一个分区使用(如
map,filter)。 - 宽依赖(Wide Dependency/Shuffle):父 RDD 的一个分区被子 RDD 的多个分区使用(如
reduceByKey,groupBy,join)。
- 窄依赖(Narrow Dependency):父 RDD 的一个分区只被子 RDD 的一个分区使用(如
- 流水线优化(Pipelining):
- Spark 会将连续的“窄依赖”操作合并到同一个 Stage 中。
- 例子:如果你连续写了
rdd.map().filter().map(),Spark 不会生成三个中间结果,而是会将这三个操作融合(Fuse)成一个函数,一条数据读进来,一口气跑完这三步。这极大地减少了中间数据的读写和网络传输。
- Stage 边界:遇到“宽依赖”(即需要 Shuffle 洗牌)时,DAG 会将其切分为新的 Stage。
C. 容错机制(Lineage 血统)
DAG 记录了 RDD 之间的依赖关系(Lineage,血统)。
- 作用:如果某个节点(机器)挂了,导致部分数据丢失,Spark 不需要重新计算整个作业。
- 它只需要查看 DAG,找到丢失的那部分数据是由哪个父 RDD 经过什么操作生成的,然后只重新计算丢失的那一小部分数据即可。
4. 总结:Spark DAG vs Hadoop MapReduce
为了更好地理解 DAG 的作用,我们可以对比一下 Hadoop MR:
- Hadoop MapReduce:
- 计算模式固定为
Map -> Shuffle -> Reduce。 - 如果任务很复杂,需要串联多个 MR 任务,每个 MR 任务结束后必须把数据写入磁盘(HDFS),下一个 MR 再读取。这导致大量的磁盘 I/O。
- 计算模式固定为
- Spark DAG:
- 计算模式是任意的 DAG 图。
- 利用 DAG,Spark 可以把多个操作在内存中通过流水线(Pipeline)完成,只有在必须 Shuffle 的时候才落盘。
- 结果:Spark 比 Hadoop 快很多(内存计算快 100 倍,磁盘计算快 10 倍)。
一句话概括
DAG 是 Spark 的导航地图。它让 Spark 在执行任务前能看到全局,从而合并步骤(流水线优化)、划分阶段(Stage),并在出错时知道如何局部修复数据(容错)。