第一章 Runtime核心机制剖析
Flink Runtime整体架构
Flink集群的基本结构
-
AppMaster包含三个组件,分别是Dispatch、ResourceManager和JobManager。Dispatcher负责为这个新提交的作业拉起一个新的JobManager组件;ResourceManager负责资源的管理,整个Flink集群只有一个RM;JobManager负责管理Job的运行,在一个Flink集群中有多个Job同时执行,每个Job都有自己的JobManager组件。
-
当用户提交作业时,
- 提交的脚本会启动一个Client进程负责作业的编译与提交,它首先将用户编写的代码编译为一个JobGraph,在这个过程还会进行一些检查或者优化等工作;
- Client产生的JobGraph提交到集群中执行.有两种情况,一种是类似于Standalone的Session模式,AM会预启动,此时Client直接与Dispatcher建立连接并提交作业;另一种是Per-Job模式,AM不会预启动,Client需要向资源管理系统(如YARN、K8S)申请资源来启动AM,然后再向AM中Dispatcher提交作业;
- 当作业到达Dispatcher后,Dispatcher会首先启动一个JobManager组件;
- JobManager向ResourceManager申请资源来启动作业中具体的任务;
- 如果是Session模式,ResourceManager已经记录了TaskExcutor注册资源,可以直接选取空闲的资源分配;如果是Per-Job,ResourceManager需要向外部资源管理系统申请资源启动TaskExecutor,然后等待TaskExecutor注册相应资源再继续选择空闲资源进程分配;
- ResourceManager选择到空闲的Slot之后,就会通知相应的TaskManager将该Slot分配给JobManager,然后TaskExecutor即兴相应的记录,会向JobManager注册;
- JobManager收到TaskExecutor注册上来的Slot后,就可以实际提交Task了.
- TaskExecutor收到JobManager提交的Task之后,会启动一个新的线程来执行该Task,Task启动就会开始进行预先指定的计算,并通过Shuffle模块互相交换数据.
-
Session模式和Per-Job模式:
- Session模式下,flink会预先启动AppMaster以及一组TaskExecutor,然后在整个集群的生命周期中会执行多个作业,Session适合规模小,执行时间短的作业;
- Per-Job模式下整个flink只执行单个作业,每个作业会独享Dispatcher和ResourceManager组件,Per-Job模式下AppMaster和TaskExecutor是按需申请的,Per-Job适合运行执行时间较长的大作业.
Flink中按照什么顺序调度Task?
- Eager调度和Lazy From Source
- Eager调度在作业启动时申请资源将所有的Task调度起来.这种调度算法用来调度可能没有终止的流作业;
- Lazy From Source则是从Source开始,按拓扑顺序急性调度.
错误恢复
- 错误分为两类:Task执行出现错误和Flink集群的Master出现错误
- Restart-all,直接重启所有Task,适合流作业
- Restart-individual,适用于Task之间没有数据传输的情况
- 针对Batch作业,Flink1.9引入了一种新的Region-Based的Failover策略,一个Flink的Batch作业中Task之间存在两种数据传输方式,一种是Pipeline类型的方式,上下游Task之间通过网络传输数据;另一种是Blocking方式,上游的Task会将数据缓存,上下游的Task可以单独执行.
未来展望
- 完善的资源管理.增加细粒度资源匹配支持.
- 统一的Stream与Batch
- 更灵活的调度策略
- Master Failover优