Flink Architecture
作为流处理的分布式系统,也要求有 cluster resource managers 来进行有效的资源分配和管理。Flink 可以和常见的集群管理工具 Hadoop YARN 和 Kubernetes 集成,也可以作为 standalone 的集群运行,甚至是作为一个 library。
Flink Cluster
Flink runtime 由两种进程组成:
- 一个 JobManager 进程
- 至少一个 TaskManager 进程
JobManager
JobManager 是 Flink 系统的协调者,它负责接收 Flink Job,调度组成 Job 的多个 Task 的执行。
同时,JobManager 还负责收集 Job 的状态信息,并管理 Flink 集群中从节点 TaskManager。
JobManager 所负责的各项管理功能,它接收到并处理的事件主要包括:
- RegisterTaskManager
- 在 Flink 集群启动的时候,TaskManager 会向 JobManager 注册,如果注册成功,则 JobManager 会向 TaskManager 回复消息 AcknowledgeRegistration。
- SubmitJob:Flink 程序内部通过 Client 向 JobManager 提交 Flink Job,其中在消息 SubmitJob 中以 JobGraph 形式描述了 Job 的基本信息。
- CancelJob:请求取消一个 Flink Job 的执行,CancelJob 消息中包含了 Job 的 ID,如果成功则返回消息 CancellationSuccess,失败则返回消息 CancellationFailure。
- UpdateTaskExecutionState:TaskManager 会向 JobManager 请求更新 ExecutionGraph 中的 ExecutionVertex 的状态信息,更新成功则返回 true。
- RequestNextInputSplit:运行在 TaskManager 上面的 Task,请求获取下一个要处理的输入 Split,成功则返回 NextInputSplit。
- JobStatusChanged:ExecutionGraph 向 JobManager 发送该消息,用来表示 Flink Job 的状态发生的变化,例如:RUNNING、CANCELING、FINISHED 等。
TaskManagers
TaskManager 也是一个 Actor,它是实际负责执行计算的 Worker,在其上执行 Flink Job 的一组 Task。
每个 TaskManager 负责管理其所在节点上的资源信息,如内存、磁盘、网络,在启动的时候将资源的状态向 JobManager 汇报。
TaskManager 端可以分成两个阶段:
- 注册阶段:TaskManager 会向 JobManager 注册,发送 RegisterTaskManager 消息,等待 JobManager 返回 AcknowledgeRegistration,然后 TaskManager 就可以进行初始化过程。
- 可操作阶段:该阶段 TaskManager 可以接收并处理与 Task 有关的消息,如 SubmitTask、CancelTask、FailTask。
如果 TaskManager 无法连接到 JobManager,这是 TaskManager 就失去了与 JobManager 的联系,会自动进入“注册阶段”,只有完成注册才能继续处理 Task 相关的消息。
Client
当用户提交一个 Flink 程序时,会首先创建一个 Client。
该 Client 首先会对用户提交的 Flink 程序进行预处理,并提交到 Flink 集群中处理,所以 Client 需要从用户提交的 Flink 程序配置中获取 JobManager 的地址,并建立到 JobManager 的连接,将 Flink Job 提交给 JobManager。
Client 会将用户提交的 Flink 程序组装一个 JobGraph,并且是以 JobGraph 的形式提交的。
一个 JobGraph 是一个 Flink Dataflow,它由多个 JobVertex 组成的 DAG。
其中,一个 JobGraph 包含了一个 Flink 程序的如下信息:JobID、Job 名称、配置信息、一组 JobVertex 等。
Tasks and Operator Chains
在 Flink 分布式执行环境中,会将多个 Operator Subtask 串起来组成一个 Operator Chain,实际上就是一个执行链。
每个执行链会在 TaskManager 上一个独立的线程中执行,如下图所示:
上图中上半部分表示的是一个 Operator Chain,多个 Operator 通过 Stream 连接,而每个 Operator 在运行时对应一个 Task。
图中下半部分是上半部分的一个并行版本,也就是对每一个 Task 都并行化为多个 Subtask。