Spark的核心是基于RDD来实现的,Spark任务调度就是如何组织任务去处理RDD中每个分区的数据,根据RDD的依赖关系构建DAG,基于DAG划分Stage,然后将每个Stage中的任务(Task)分发到指定的节点去运行得到最终的结果。
大概流程如下:
当Spark程序遇到1个Action算子时, 会产生一个Job任务, 首先你代码层面上要创建一个SparkContext 对象, 同时其底层也会创建 DAGScheduler 和 TaskScheduler .
首先DAGScheduler 负责生成 DAG 执行流程图 , 划分阶段Stage, 并确定每个阶段有多少个线程,
然后把每个阶段的线程放置到一个TaskSet中, 提交给TaskScheduler , TaskScheduler遍历每一个TaskSet , 将其尽可能均衡地分配给 Executor 来运行, 最后Driver 进行监控管理即可.
这个我引用知乎的一张图方便理解:
了解这个流程你要明白几个词的意思:
Job(作业):由Action算子触发生成的由一个或多个Stage组成的计算作业。
Stage(调度阶段):每个Job会根据RDD的宽依赖被切分为多个Stage,每个Stage都包含一个TaskSet。
TaskSet(任务集):一组关联的,但相互之间没有shuffle依赖关系的Task集合。一个TaskSet对应的调度阶段。
Task(任务):RDD中的一个分区对应一个Task,Task是单个分区上最小的处理流程单元。