

# 工作和调度

> 译者：[flink.sojb.cn](https://flink.sojb.cn/)


本文档简要介绍了Flink如何调度作业及其如何表示和跟踪JobManager上的作业状态。

## 调度

Flink中的执行资源通过_任务槽_定义。每个TaskManager都有一个或多个任务槽，每个槽都可以运行一个并行任务管道。流水线由多个连续的任务，如在 _第n_一MapFunction的连同并行实例_第n_一ReduceFunction的并行实例。请注意，Flink经常同时执行连续任务：对于流程序，无论如何都会发生，但对于批处理程序，它经常发生。

下图说明了这一点。考虑一个带有数据源，_MapFunction_和_ReduceFunction的程序_。源和MapFunction以4的并行度执行，而ReduceFunction以3的并行度执行。管道由序列Source - Map - Reduce组成。在具有2个TaskManagers且每个具有3个插槽的群集上，程序将按如下所述执行。

![将任务管道分配给插槽](../img/slots.svg)

在内部，Flink限定通过[SlotSharingGroup](https://github.com/apache/flink/blob/master//flink-runtime/src/main/java/org/apache/flink/runtime/jobmanager/scheduler/SlotSharingGroup.java) 和[CoLocationGroup](https://github.com/apache/flink/blob/master//flink-runtime/src/main/java/org/apache/flink/runtime/jobmanager/scheduler/CoLocationGroup.java) 哪些任务可以共享的狭槽（许可），分别哪些任务必须严格放置到相同的时隙。

## JobManager数据结构

在作业执行期间，JobManager会跟踪分布式任务，决定何时安排下一个任务（或一组任务），并对已完成的任务或执行失败做出反应。

[JobManager](https://github.com/apache/flink/blob/master//flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/)接收[JobGraph](https://github.com/apache/flink/blob/master//flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/)，它是由 算子（[JobVertex](https://github.com/apache/flink/blob/master//flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/JobVertex.java)）和中间结果（[IntermediateDataSet](https://github.com/apache/flink/blob/master//flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/IntermediateDataSet.java)）组成的数据流的表示。每个 算子都具有属性，例如并行性和它执行的代码。此外，JobGraph还有一组附加库，这些库是执行算子代码所必需的。

JobManager将JobGraph转换为[ExecutionGraph](https://github.com/apache/flink/blob/master//flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/)。ExecutionGraph是JobGraph的并行版本：对于每个JobVertex，它包含每个并行子任务的[ExecutionVertex](https://github.com/apache/flink/blob/master//flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/ExecutionVertex.java)。并行度为100的 算子将具有一个JobVertex和100个ExecutionVertices。ExecutionVertex跟踪特定子任务的执行状态。来自一个JobVertex所有ExecutionVertices都保存在 [ExecutionJobVertex中](https://github.com/apache/flink/blob/master//flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/ExecutionJobVertex.java)，它跟踪整个算子的状态。除了顶点之外，ExecutionGraph还包含[IntermediateResult](https://github.com/apache/flink/blob/master//flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/IntermediateResult.java)和[IntermediateResultPartition](https://github.com/apache/flink/blob/master//flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/IntermediateResultPartition.java)。前者跟踪_IntermediateDataSet_的状态，后者是每个分区的状态。

![JobGraph和ExecutionGraph](../img/job_and_execution_graph.svg)

每个ExecutionGraph都有一个与之关联的作业状态。此作业状态指示作业执行的当前状态。

Flink作业首先处于_创建_状态，然后切换到_运行，_并在完成所有工作后切换到已_完成_。如果出现故障，作业将首先切换为取消所有正在运行的任务的_失败_。如果所有作业顶点都已达到最终状态且作业无法重新启动，则作业将转换为_失败_。如果可以重新启动作业，则它将进入_重新启动_状态。作业完全重新启动后，将达到_创建_状态。

如果用户取消作业，它将进入_取消_状态。这还需要取消所有当前正在运行的任务。一旦所有正在运行的任务都达到最终状态，作业将转换为_已取消_的状态。

与_完成_，_取消_和_失败_的状态不同，它表示全局终端状态，因此触发清理作业，_暂停_状态仅在本地终端。本地终端意味着作业的执行已在相应的JobManager上终止，但Flink集群的另一个JobManager可以从持久性HA存储中检索作业并重新启动它。因此，到达_暂停_状态的作业将不会被完全清除。

![Flink工作的状态和转型](../img/job_status.svg)

在执行ExecutionGraph期间，每个并行任务都经历多个阶段，从_创建_到_完成_或_失败_。下图说明了它们之间的状态和可能的转换。可以多次执行任务（例如，在故障恢复过程中）。因此，在Execution中跟踪[ExecutionVertex执行](https://github.com/apache/flink/blob/master//flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/Execution.java)。每个ExecutionVertex都有一个当前的Execution和先前的Executions。

![任务执行的状态和转变](../img/state_machine.svg)