flink架构体系
JobManager处理器
- 也称之为Master,用于协调分布式执行,它们用来调度task,协调检查点(CheckPoint),协调失败时恢复等。
- 负责资源申请,任务分发,任务调度执行,checkpoint的协调执行;
- Flink运行时至少存在一个master处理器,如果配置高可用模式则会存在多个master处理器,它们其中有一个是leader,而其他的都是standby。
TaskManager处理器
- 也称之为Worker,用于执行一个dataflow的task(或者特殊的subtask)、数据缓冲和data stream的交换,Flink运行时至少会存在一个worker处理器。
- 负责任务的执行,基于dataflow(spark中DAG)划分出的task;与jobmanager保持心跳,汇报任务状态。
flink运行架构
flink的程序结构
- 1)
source
读取数据 - 2)
transformation
用对数据流进行转换操作 - 3)
sink
将处理后的数据输出到下游
flink的并行数据流
Flink程序在执行的时候,会被映射成一个Streaming Dataflow
,一个Streaming Dataflow
是由一组Stream
和Transformation Operator
组成的。在启动时从一个或多个Source Operator
开始,结束于一个或多个Sink Operator
。
- flink中
stream dataflow
是并行化的
- 在执行过程中,一个流包含一个或多个流分区;而每一个operator包含一个或多个operator子任务。
- 比如下图中一个
Source Operator
可以有两个并行度,这两个并行度在flink里面会有两个subtask
来处理
- operator子任务间彼此独立,在不同的线程中执行,甚至是在不同的机器或不同的容器上。
- operator子任务的数量就是operator的并行度。相同程序中的不同operator有不同的并行度。
- 一个
Stream
可以被分成多个Stream
的分区,也就是Stream Partition
。 - 一个
Operator
也可以被分为多个Operator Subtask
。
- 如上图中,Source被分成Source1和Source2,它们分别为Source的
Operator Subtask
。 - 每一个
Operator Subtask
都是在不同的线程当中独立执行的。 - 一个Operator的并行度,就等于
Operator Subtask
的个数。上图Source的并行度为2。 - 一个Stream的并行度就等于它生成的Operator的并行度。
数据在两个operator之间传递的时候有两种模式:
- One to One 模式
- 一对一模式,两个operator用此模式传递的时候,会保持上游每个
stream partition
中数据的分区和排序,传递给下游某个分区;没有类似shuffle的操作。 - 如上图中的Source1到Map1,它就保留的Source的分区特性,以及分区元素处理的有序性。
- Redistributing (重新分配)模式
- 重新分区,类似shuffle操作,数据会在上下游算子不同的subtask中分散。
- 例如上图中的
keyby
操作,会从不同的subtask
里来拉取数据
Task和Operator chain(操作链)
- Flink的所有操作都称之为Operator,客户端在提交任务的时候会对Operator进行优化操作;
- 能进行合并的Operator(
one to one
模式的Operator
)会被合并为一个Operator,合并后的Operator称为Operator chain
,实际上就是一个执行链
- 例如下图中
source
和map
操作会合并成一个task
,如果这个时候是两个task
,可能在不同的taskManager
上,此时可能会有数据的分散,把他们合并之后,相当于在一个task上,数据就在一个线程上,这样就避免了数据的远程发送,提高了效率
- 每个执行链会在
TaskManager
上一个独立的线程中执行。
flink任务调度流程
流程图如下
具体流程
- 1)当Flink执行executor会自动根据程序代码生成DAG数据流图
- 2)ActorSystem创建Actor将数据流图发送给JobManager中的Actor
- flink中不同的角色之间都是通过Actor来通信,程序拿到Client之后会通过Akka客户端来通信
- 3)JobManager会不断接收TaskManager的心跳消息,从而可以获取到有效的TaskManager
- 3)JobManager接收到数据之后就会进行数据的并行化、合并成操作链等优化操作,最后将每个
operator chain
的subtask
再分发给TaskManager
- 4)JobManager通过调度器在TaskManager中调度执行Task(在Flink中,最小的调度单元就是task,对应就是一个线程)
TaskManager
里面有一个slot
的概念,slot
是真正负责任务的执行
- slot是flink里面任务调度的基本资源单位,一个slot会处理一个任务
- 如上图中,总共两个
TaskManager
,每个TaskManager
里有三个slot,那么flink的最大task并行数量就是6 - 在程序运行过程中,task与task之间是可以进行数据传输的,例如出现keyby操作时
角色介绍
job client
- 是用户编写的代码,将flink的客户端封装好的提交任务的客户端;
- 主要作用:
- 提交任务,不是flink内部的一个角色。
- 接收用户编写的代码,创建
stream dataflow
,提交给jobmanager
,接收任务的执行结果并返回给客户;
jobmanager
- 主要职责是调度工作并协调任务做检查点
- 负责接收任务,对任务进行优化,并调度和执行任务
- 做检查点主要由调度器和
checkpoint coordinator
(ck协调器)来完成
- JobManager从客户端接收到任务以后, 首先生成优化过的执行计划,再调度到TaskManager中执行
TaskManager
- 主要职责是从JobManager处接收任务, 并部署和启动任务, 接收上游的数据并处理
- 从jobmanager中接收task,部署到自己的slot中并执行
- TaskManager实际执行任务都是以线程的形式执行(更轻量级)
- TaskManager在创建之初就设置好了Slot, 每个Slot可以执行一个任务
slot(任务槽)
- slot是flink中从资源层面进行调度的单位
- 特点:slot是会平均划分当前TaskManager中内存
- flink程序的最大并行度就是所有TaskManager中的slot的数量(我们flink控制可以接收的任务数量就是通过slot数量来实现)
- slot数量如何确定:保持和TaskManager中的cpu核数一样,保证任务执行的性能。
- slot实际是任务执行的真正角色。
slot sharing
- 槽共享,默认情况下,Flink允许子任务共享插槽,即使它们是不同任务的子任务,只要它们来自同一个作业。结果是一个槽可以保存作业的整个管道。
- 每个slot都可以接收当前作业的任何子任务,这样充分利用了当前所有slot来提高并行度。
- 例如下图中,整个作业划分为13个
subtask
,有6个slot
,如果不允许槽共享,那么第一行的6个subtask
就已经把6个slot占满了,其他的subtask
例如keyBy()
就没地方放了