揭秘 Spark 源码:Task 启动的前世今生
2023-11-01 15:51:33
Spark 源码分析(九):Task 启动
前面已经分析到了 DAGScheduler 对 stage 划分,并对 Task 的最佳位置进行计算之后,通过调用 taskScheduler 的 submitTasks 方法,将每个 stage 的 taskSet 进行提交。 在 taskScheduler 的 submitTasks 方法中,会首先根据每个 taskSet 的最佳位置,将 taskSet 提交到对应的 Executor 上。接下来,Executor 会根据 taskSet 中包含的 task,创建并启动对应的 TaskRunner,并执行 task。
DAG Scheduler 如何划分 Stage
DAG Scheduler 会根据 Job 的依赖关系,将 Job 划分为多个 Stage。每个 Stage 对应一个 RDD,并且包含了该 RDD 上需要执行的所有操作。DAG Scheduler 在划分 Stage 时,会考虑以下几个因素:
- 数据依赖关系: Stage 之间的划分必须保证数据依赖关系。如果一个 Stage 的输出数据会被另一个 Stage 使用,那么这两个 Stage 必须被划分在同一个 Job 中。
- 任务粒度: Stage 中的任务粒度要适中。如果任务粒度太小,会导致任务数量过多,增加任务调度的开销。如果任务粒度太大,会导致任务执行时间过长,降低系统的吞吐量。
- 资源利用率: DAG Scheduler 会尽量将任务分配到资源利用率较高的 Executor 上,以提高资源利用率。
Task Scheduler 如何计算最佳位置
Task Scheduler 在提交 taskSet 时,会根据每个 task 的数据依赖关系和 Executor 的资源利用率,计算出每个 task 的最佳位置。最佳位置是指能够使 task 尽快执行完成的位置。
Task Scheduler 在计算最佳位置时,会考虑以下几个因素:
- 数据本地性: 如果一个 task 的输入数据已经保存在某个 Executor 的本地磁盘上,那么这个 task 最好在该 Executor 上执行。这样可以避免数据在网络上传输,从而提高任务的执行速度。
- 资源利用率: Task Scheduler 会尽量将 task 分配到资源利用率较高的 Executor 上,以提高资源利用率。
- 任务优先级: 如果一个 task 的优先级较高,那么 Task Scheduler 会优先将该 task 分配到资源利用率较高的 Executor 上,以确保该 task 能够尽快执行完成。
Executor 如何启动 Task
当 Executor 收到 taskSet 后,会根据 taskSet 中包含的 task,创建并启动对应的 TaskRunner,并执行 task。
TaskRunner 是一个线程,它负责执行 task。TaskRunner 在执行 task 时,会首先加载 task 所需的类和资源,然后执行 task 的计算逻辑。当 task 执行完成后,TaskRunner 会将 task 的结果返回给 Driver。
结论
本文通过对 Spark 源码的逐层剖析,详细介绍了 Spark 中 Task 启动的过程。读者通过本文可以全面了解 Spark 任务调度的奥秘,并能够根据需要对 Spark 任务调度进行优化。