概念
概念
一、Flink 运行架构
这里需要提到 Flink 中的几个关键组件:客户端(Client)、作业管理器(JobManager)和 任务管理器(TaskManager)。我们的代码,实际上是由客户端获取并做转换,之后提交给 JobManger 的。所以 JobManager 就是 Flink 集群里的“管事人”,对作业进行中央调度管理; 而它获取到要执行的作业后,会进一步处理转换,然后分发任务给众多的 TaskManager。这里的TaskManager,就是真正“干活的人”,数据的处理操作都是它们来做的。
复杂版
二、Flink 运行时的组件
作业管理器(JobManager)
- 控制一个应用程序执行的主进程,也就是说,每个应用程序都会被一个不同的 JobManager 所控制执行。
- JobManager 会先接收到要执行的应用程序,这个应用程序会包括: 作业图(JobGraph)、逻辑数据流图(logical dataflow graph)和打包了所有的类、库和其它 资源的 JAR 包。
- JobManager 会把 JobGraph 转换成一个物理层面的数据流图,这个图被叫做 “执行图”(ExecutionGraph),包含了所有可以并发执行的任务。
- JobManager 会向资源管 理器(ResourceManager)请求执行任务必要的资源,也就是任务管理器(TaskManager)上 的插槽(slot)。一旦它获取到了足够的资源,就会将执行图分发到真正运行它们的 TaskManager 上。而在运行过程中,JobManager 会负责所有需要中央协调的操作,比如说检 查点(checkpoints)的协调。
高可用得多个,但是实际使用的还是一个,其他都是Standby。
资源管理器(ResourceManager)
在JobManager里
- 主要负责管理任务管理器(TaskManager)的插槽(slot),TaskManger 插槽是 Flink 中 定义的处理资源单元。
- Flink 为不同的环境和资源管理工具提供了不同资源管理器,比如 YARN、Mesos、K8s,以及 standalone 部署。
- 当 JobManager 申请插槽资源时,ResourceManager 会将有空闲插槽的TaskManager分配给JobManager。如果ResourceManager没有足够的插槽 来满足 JobManager 的请求,它还可以向资源提供平台发起会话,以提供启动 TaskManager 进程的容器。另外,ResourceManager 还负责终止空闲的 TaskManager,释放计算资源。
分发器(Dispatcher)
在JobManager里
- 可以跨作业运行,它为应用提交提供了 REST 接口。
- 当一个应用被提交执行时,分发器 就会启动并将应用移交给一个 JobManager。由于是 REST 接口,所以 Dispatcher 可以作为集 群的一个 HTTP 接入点,这样就能够不受防火墙阻挡。
- Dispatcher 也会启动一个 Web UI,用 来方便地展示和监控作业执行的信息。
- Dispatcher 在架构中可能并不是必需的,这取决于应 用提交运行的方式。
任务管理器(TaskManager)
- Flink 中的工作进程。通常在 Flink 中会有多个 TaskManager 运行,每一个 TaskManager都包含了一定数量的插槽(slots)。插槽的数量限制了 TaskManager 能够执行的任务数量。
- 启动之后,TaskManager 会向资源管理器注册它的插槽;收到资源管理器的指令后, TaskManager 就会将一个或者多个插槽提供给 JobManager 调用。JobManager 就可以向插槽 分配任务(tasks)来执行了。
- 在执行过程中,一个 TaskManager 可以跟其它运行同一应用程 序的 TaskManager 交换数据。
三、提交作业流程
抽象的流程
Standalone(会话)作业提交流程
Yarn(会话)作业提交流程
Yarn(单作业)提交流程
四、一些重要概念
数据流图(DataFlow)
所有的Flink程序都是由三部分组成:Source、Transformation和Sink。
Source负责读取数据源,Transformation 利用各种算子进行处理加工,Sink负责输出。
在运行时,Flink上运行的程序会被映射成"逻辑数据流"(dataflows),它包含了这三部分
每一个dataflow以一个或多个sources开始以一个或多个sinks结束。dataflow类似于任意的有向无环图(DAG)
在大部分情况下,程序中的转换运算(transformations)跟dataflow中的算子(operator)是一一对应的关系
执行图(ExecutionGraph)
Flink中的执行图可以分成四层:StreamGraph -> JobGraph -> ExecutionGraph -> 物理执行图
- StreamGraph:是根据用户通过Stream API编写的代码生成的最初的图。用来表示程序的拓扑结构。
- JobGraph:StreamGraph经过优化后生成了JobGraph,提交给JobManager的数据结构。主要的优化为,将多个符合条件的节点chain在一起作为一个节点
- ExecutionGraph:JobManager根据JobGraph生成ExecutionGraph。是JobGraph的并行化版本,是调度层最核心的数据结构。
- 物理执行图:JobManager根据ExecutionGraph对Job进行调整后,在各个TaskManager上部署Task后形成的"图",并不是一个具体的数据结构。
算子链(Operator Chains)
一个程序中,不同的算子可能具有不同的并行度,算子之间传输数据的形式可以是one-toone(forwarding)的模式也可以是redistributing的模式,具体是哪一种形式,取决于算子的种类
- One-to-one: stream维护者分区以及元素的顺序(比如source和map之间)。这意味着map算子的子任务看到的元素的个数以及顺序跟source算子的子任务生产的元素的个数、顺序相同。map、fliter、flatMap等算子都是one-to-one的对应关系。
- Redistributing:stream的分区会发生改变。每一个算子的子任务根据所选择的transformation发送数据到不同的目标任务。例如,keyBy基于hashCode重分区、而broadcast和rebalance会随机重新分区,这些算子都会引起redistribut过程,而redistribute过程就类似于Spark中的shuffle过程。
Flink采用了一种称为任务链的优化技术,可以在特定条件下减少本地通信的开销,并通过本地转发(local forward)的方式进行连接相同不行度的one-to-one操作,Flink这样相连的算子链接在一起形成一个task,原来的算子成为里面的subtask。
并行度相同、并且是one-to-one操作,两个条件缺一不可
Task Slots
Task Slots是指TaskManager具有的并发执行能力,通过参数taskmanager.numberOfTaskSlots
进行配置
Flink中每一个TaskManager都是一个JVM进程,它可能会在独立的线程上执行一个或多个子任务
为了控制一个TaskManager能接受多少个task,TaskManager通过task slot来进行控制(一个TaskManager至少有一个slot)
默认情况下,Flink允许子任务共享slot。这样的结果是,一个slot可以保存作业的整个管道。
当我们将资源密集型和非密集型的任务同时放到一个slot中,它们就可以自行分配对资源占用的比例,从而保证最重要的活平均分配给所有的TaskManager。