Flink部署模式
以集群的生命周期以及资源的分配模式分为:
会话模式(session mode)
先起集群,再提交作业,作业和集群生命周期没有关系。集群启动了所有资源就都已经确定了,所有提交的作业会竞争集群中的资源。这种模式下最好结合另外的资源管理平台(比如yarn),比较实用;
会话模式适合单个规模小、执行时间短的大量作业;
单作业模式(per-job mode)
作业集群1对1,集群只为这个作业而生。可以避免会话模式因为资源共享而导致资源紧张、竞争的问题。
单作业模式是实际生产应用中的首选(实际应用比较大)
Flink本身无法直接这样运行,所以单作业模式一般需要借助资源管理器
应用模式(application mode)
应用模式和单作业方式都是提交之后才创建集群,单作业模式是通过客户端来提交的,客户端解析出每一个作业对应的集群;而应用模式下,是直接由JobManager执行应用程序的,即使应用包含多个作业,也只创建一个集群。
以上的部署模式是相对抽象的概念,我们一般需要结合资源管理平台,选择特定的模式来分配资源、部署应用:
Standalone
最简单的方式,不借助外部资源管理平台
缺点:如果出现资源不足、故障,没有自动扩展或者重新分配资源机制,必须要手动处理
Yarn
Flink任务部署到YRAN集群前,需要确认集群是否安装了Hadoop,并且集群中安装了HDFS服务
会话模式
/bin/yarn-session.sh
一般来说会话模式资源是集群启动时就确定的,是静态分配,缺点明显,但是由于我们用的是yarn,可以进行资源动态分配,所以启动yarn-session.sh时候就不必指定资源信息了(taskManager和slots数量)
单作业模式
Flink运行时组件
作业管理器(JobManager)
控制一个应用程序执行的主进程,是Flink集群中任务管理和调度的中心。
组成模块
Jobmaster
原Flink旧版本的jobManager,新版本的Flink将resouceManager和Dispacher合到jobManager中,并将原来的jobManager改成jobmaster
- 接收执行的应用程序,应用程序包括作业图(Job Graphic)和逻辑数据流图(logical dataflow graphic)和打包的类、库和jar包资源
- 把作业图转换成(可落地执行的)物理数据流图——执行图(ExecutionGraphic)
- 向ResourceManager请求执行所需资源,即任务管理器(TaskManager)上的slot
- 将执行图分发到真正执行运行的TaskManager上
- 运行过程中负责中央协调操作,比如检查点(checkpoint)协调
ResourceManager
资源管理器,主要负责管理TaskManager的slot,slot是Flink定义的最小处理资源单元。
Flink为不同的环境和资源管理工具提供不同资源管理器,如YARN、Mesos、K8s以及standalone部署。
Dispacher
分发器,为应用提交提供REST接口、将提交的应用转发给一个JobManager、启动WEB UI相关。
Dispacher在架构中不是必须的,取决于应用提交方式。
任务管理器(TaskManager)
Flink中的工作进程。每个TaskManager包含一定数量的slots,slots数量限制了TaskManager能够执行的任务数量。
- 启动之后,TaskManager会向ResourceManager注册他的slots
- 收到ResourceManager命令后,TaskManager会将slot供JobManager使用,JobManager会向slot分配执行任务
- 在执行过程中,同个应用下的TaskManager可以交换数据
Flink任务提交流程
统一抽象提交流程图
简而言之:应用程序(作业图) -> 执行图 -> (向RM)申请资源 -> 分发执行图(TaskManager)执行作业
YARN提交流程图(Per Job)
Flink任务调度原理
编码code -> 生成逻辑数据流图(Dataflow graphic)-> cliet发送(命令行或者Dispacher)
Slot分配
并行子任务分配
可以定制化配置策略比如C分配到Slot1.1和Slot1.2,默认行为也许是随机的?
任务分配实例分析
任务划分
同Spark依据宽依赖、窄依赖将Job划分成若干个Stage一样。
数据传输形式
Flink程序由三部分组成:Source > Transformation > Sink
Source负责读取数据源,Transformation利用各种算子进行加工处理,sink负责输出
算子之间传输数据的形式可以是one-to-one(forwarding)的模式也可以是redistributiing的模式,具体是哪一种形式,取决于算子的类型
- one-to-one:stream维护者分区以及元素的顺序(比如source和map之间)。意味着map的算子的子任务看到的元素的个数以及顺序跟source算子的子任务生产的元素个数、顺序相同。map、filter、flatmap等算子都是one-to-one的对应关系
- Redistributing:stream分区会发生改变。每一个算子的子任务依据所选择的transformation发送数据到不同的目标分区。例如,keyBy基于hashCode重分区、broadcast和rebalance会随机重新分区,这些算子都会引起redistribute,redistribute过程类似于spark的shuffle过程
任务链
相同并行度的one-to-one的算子链接在一起会合并一个任务,即任务链优化技术。
优点是直接变成本地调用,节约了传输成本极大提升了性能
概念扩展说明
并行度 parallelism
一个特定算子的子任务(subtask)的个数被称为并行度(parallelism)。一般情况下,当前流的并行度是指其所有算子中最大的并行度。
TaskManager和Slots
Flink中每一个TaskManager都是一个JVM进程,会在独立的线程上执行一个或多个子任务。为了控制一个TaskManager能接收多少个task,TaskManager通过task slot来控制。
slot是独立内存的分配,是内存隔离的,但不同任务之间,slot默认是可以共享的
默认情况下,Flink允许子任务共享slot,即使他们是不同任务的子任务。这样的结果是一个slot可以保存作业的整个管道。
Task Slot是静态概念,是指TaskManager具有的并发执行能力,主要是用于内存隔离资源
执行图(ExecutionGraph)
Flink的执行图可以分四层:StreamGraph > JobGraph > ExecutionGraph > 物理执行图
- StreamGraph:根据Stream API(代码)编写代码生成最初的图
- JobGraph:StreamGraph经过优化后生成JobGraph,提交给JobManager的数据结构。主要优化是将多个符合条件的节点chain在一起作为一个节点
- ExecutionGraph:JobManager根据JobGraph生成ExecutionGraph。ExecutionGraph是JobGraph的并行化版本,细化到每个任务的并行度以及再分区(redistribute)逻辑,是调度层最核心的数据结构。
- 物理执行图:JobManager根据ExecutionGraph对Job进行调度后,在各个TaskManager