Flink架构
Flink为了执行流式应用,要求对计算资源进行合理分配和管理。Flink有多种实现自身功能的方式:
- Flink可以和常见的集群资源管理器(YARN/K8S等)进行交互
- Flink可以使用
Standalone(独立集群模式)来运行 - Flink可以作为一个库来运行
Flink的主要组件 & 如何交互执行任务
Flink运行时包含两种进程:1个JobManager,1个或多个TaskManager。
如图所示,Client既不是Flink运行时的一部分,也不是Flink所要执行任务的一部分。但是Client可以作为触发任务执行的Java/Scala代码或者以命令行的形式存在: (./bin/flink run ...)
JobManager和TaskManager有多种启动的方式:1. 独立集群模式(standalone) 2. 与其他集群进行交互的方式。
TaskManager连接到JobManager,并且宣称它们是正常可工作的,由JobManager来分配工作给TaskManager任务。
Flink 架构图
JobManager
JobManager在执行Flink分布式应用的时候负责多种协调工作:
- 决定何时调度下一个task
- 对成功完成/失败的task做出反应
- 协调
checkpoints - 协调故障恢复等等
JobManager具有三个主要的组件:
- ResourceManager
- 负责Flink集群资源的分配/回收和配置
- 管理Flink集群资源调度的最小单元 -->
task slots - Flink对于不同的执行环境/集群环境(K8S/YARN/Standalone)提供了多种不同的
ResourceManager,如:在Standalone模式下,ResourceManager只能够分配可用的TaskManager的task slots,并不能创建新的TaskManager。
- Dispatcher
- 为Flink应用的执行提供了
REST接口 - 为每个提交的任务启动一个新的
JobMaster - 运行Flink的Web UI
- 为Flink应用的执行提供了
- JobMaster
- 管理一个单一的
JobGraph的执行,在Flink集群中同时运行的多个Job中,每一个Job都拥有一个JobMaster
- 管理一个单一的
一个Flink集群至少拥有一个JobManager,高可用的分布式系统可能会拥有多个JobManager。在高可用情况下,其中一个
Jobmanager是正主,其他的JobManager是备胎。
TaskManager
TaskManager通常还被称为Worker,TaskManager执行数据流任务,缓存、交换数据流。
在一个Flink的集群中,至少要有一个TaskManager,task slot是TaskManager中资源调度的最小单位。TaskManager中task slot的数量表示了TaskManager同时可处理task的数量。
多个算子(operator)可能在同一个task slot中执行
Task 和 operator chains
一系列operator连接成的链叫做task,每一个task被一个线程执行,这种operator chains结构的好处:
- 减少了线程与线程之间切换和缓存所带来的开销
- 提高了吞吐量
- 减少了延时
Task Slot 和 资源
每一个TaskManager都是一个JVM的进程,可能会在不同的线程中执行一个或多个任务。为了控制一个TaskManager需要接受多少个任务,task slot(任务槽)的概念产生了。
每一个TaskManager至少要拥有一个task slot,每一个task slot代表的是TaskManager的混合资源的子集合。
TaskManager会将其管理的内存平分给其拥有的task slot,分配资源意味着一个作业的子任务不会和其他作业的子任务争抢资源,而是有一定数量的保留托管内存。这里不隔离(分配)CPU的资源。
通过调整task slot的数量,用户可以定义子任务之间如何隔离:
- 每一个
TaskManager只拥有一个slot,意味着每个任务组在单独分开的JVM中运行 - 每一个
TaskManager拥有多个slot,意味着多个子任务共享同一个JVM - 共享同一个JVM的多个子任务之间共享TCP连接、心跳信息,分享数据以及数据结构,减小每一个任务的开销
默认情况下,Flink允许多个子任务共享同一个task slot,只要他们是来自于同一个Job,一个task slot可能掌握着一个Job的整个流水线。任务槽共享有两个好处:
- Flink 集群需要与作业中使用的最高并行度一样多的任务槽。不需要计算一个程序中包含的任务总数。
- 更容易获得更好的资源利用率。如果没有插槽共享,非密集型
source/map()子任务将阻塞与资源密集型窗口子任务一样多的资源。通过插槽共享,将我们示例中的基本并行度从两个增加到六个可以充分利用插槽资源,同时确保繁重的子任务在 TaskManager 之间公平分配。
Flink程序的执行
Flink应用程序是包含一个或多个Job的用户程序,这些Job能够在本地执行(Standalone),也可以在远程部署的集群上(YARN/K8S)部署。对于每一个Flink应用程序,执行环境提供了控制任务执行以及与外界交互的方法。