大数据

Spark Task 的执行流程② – 创建、分发 Task

本文为 Spark 2.0 源码分析笔记,由于源码只包含 standalone 模式下完整的 executor 相关代码,所以本文主要针对 standalone 模式下的 executor 模块,文中内容若不特意说明均为 standalone 模式内容

创建 task(driver 端)

task 的创建本应该放在分配 tasks 给 executors一文中进行介绍,但由于创建的过程与分发及之后的反序列化执行关系紧密,我把这一部分内容挪到了本文。

创建 task 是在 TaskSetManager#resourceOffer(...) 中实现的,更准确的说是创建 TaskDescription,task 及依赖的环境都会被转换成 byte buffer,然后与 taskId、taskName、execId 等一起构造 TaskDescription 对象,该对象将在之后被序列化并分发给 executor 去执行,主要流程如下:

从流程图中可以看出,task 依赖了的文件、jar 包、设置的属性及其本身都会被转换成 byte buffer

分发 task(driver 端)

分发 task 操作是在 driver 端的 CoarseGrainedSchedulerBackend#launchTasks(tasks: Seq[Seq[TaskDescription]]) 中进行,由于上一步已经创建了 TaskDescription 对象,分发这里要做的事就很简单,如下:

仅仅是序列化了 TaskDescription 对象并发送 LaunchTask 消息给 CoarseGrainedExecutorBackend

worker 接收并处理 LaunchTask 消息

LaunchTask 消息是由 CoarseGrainedExecutorBackend 接收到的,接收到后的处理流程如下:

接收到消息后,CoarseGrainedExecutorBackend 会从消息中反序列化出 TaskDescription 对象并交给 Executor 去执行;Executor 利用 TaskDescription 对象创建 TaskRunner 然后提交到自带的线程池中执行。

关于 TaskRunner、线程池以及 task 具体是如何执行的,将会在下一篇文章中详述,本文只关注创建、分发 task 的过程。