文章目录

  • 01 引言
  • 02 Flink角色
  • 03 Flink执行流程
  • 3.1 Standalone版本
  • 3.2 on yarn
  • 04 Flink Streaming Dataflow
  • 4.1 Flink相关词汇
  • 4.2 Operator传递模式
  • 4.3 Operator Chain
  • 4.4 任务槽与槽共享
  • 4.4.1 任务槽(TaskSlot)
  • 4.4.2 槽共享(Slot Sharing)
  • 05 Flink运行时组件
  • 5.1 作业管理器(JobManager)
  • 5.2 任务管理器(TaskManager)
  • 5.3 资源管理器(ResourceManager)
  • 5.4 分发器(Dispatcher)
  • 06 Flink执行图(ExecutionGraph)
  • 6.1 原理

01 引言

在前面的博客,我们运行了简单的Flink案例了,有兴趣的同学可以参阅下:

  • 《Flink教程(01)- Flink知识图谱》
  • 《Flink教程(02)- Flink入门》
  • 《Flink教程(03)- Flink环境搭建》
  • 《Flink教程(04)- Flink入门案例》

本文简单讲解Flink的原理。

02 Flink角色

在实际生产中,​​Flink​​ 都是以集群在运行,在运行的过程中包含了两类进程。

Flink有如下角色:

  • JobManager​:它扮演的是集群管理者的角色,负责调度任务、协调​​checkpoints​​​、协调故障恢复、收集​​Job​​​ 的状态信息,并管理​​Flink​​​集群中的从节点​​TaskManager​​;
  • TaskManager​:实际负责执行计算的​​Worker​​​,在其上执行​​Flink Job​​​的一组​​Task​​​;​​TaskManager​​​还是所在节点的管理员,它负责把该节点上的服务器信息比如内存、磁盘、任务运行情况等向​​JobManager​​ 汇报。
  • Client​:用户在提交编写好的​​Flink​​​工程时,会先创建一个客户端再进行提交,这个客户端就是​​Client​​。

Flink教程(05)- Flink原理简单分析_大数据

Flink教程(05)- Flink原理简单分析_flink_02

03 Flink执行流程

3.1 Standalone版本

Flink教程(05)- Flink原理简单分析_插槽_03

3.2 on yarn

Flink教程(05)- Flink原理简单分析_Flink_04

上述流程:

  1. ​Client​​​向​​HDFS​​​上传​​Flink​​​的​​Jar​​包和配置 ;
  2. ​Client​​​向​​Yarn ResourceManager​​提交任务并申请资源;
  3. ​ResourceManager​​​分配​​Container​​​资源并启动​​ApplicationMaster​​​,然后​​AppMaster​​​加载​​Flink​​​的​​Jar包​​​和配置构建环境,启动​​JobManager​​;
  4. ​ApplicationMaster​​​向​​ResourceManager​​​申请工作资源,​​NodeManager​​​加载​​Flink​​​的​​Jar​​​包和配置构建环境并启动​​TaskManager​​;
  5. ​TaskManager​​​启动后向​​JobManager​​​发送心跳包,并等待​​JobManager​​向其分配任务。

04 Flink Streaming Dataflow

4.1 Flink相关词汇

官网关于​​Flink​​​的词汇表:https://ci.apache.org/projects/flink/flink-docs-release-1.11/concepts/glossary.html#glossary

  • Dataflow​:​​Flink​​程序在执行的时候会被映射成一个数据流模型
  • Operator​:数据流模型中的每一个操作被称作​​Operator​​​,​​Operator​​​分为:​​Source/Transform/Sink​
  • Partition​:数据流模型是分布式的和并行的,执行中会形成​​1~n​​个分区
  • Subtask​:多个分区任务可以并行,每一个都是独立运行在一个线程中的,也就是一个​​Subtask​​子任务
  • Parallelism​:并行度,就是可以同时真正执行的子任务数/分区数

Flink教程(05)- Flink原理简单分析_大数据_05

4.2 Operator传递模式

数据在两个​​Operator​​(算子)之间传递的时候有两种模式:

  • One to One模式:两个​​operator​​​用此模式传递的时候,会保持数据的分区数和数据的排序;如上图中的​​Source1​​​到​​Map1​​​,它就保留的​​Source​​的分区特性,以及分区元素处理的有序性。
  • Redistributing 模式:这种模式会改变数据的分区数 ,每个一个​​operator subtask​​​会根据选择​​transformation​​​把数据发送到不同的目标​​subtasks​​​,比如​​keyBy()​​​会通过​​hashcode​​​重新分区,​​broadcast()​​​和​​rebalance()​​方法会随机重新分区。

4.3 Operator Chain

Flink教程(05)- Flink原理简单分析_大数据_06

客户端在提交任务的时候会对​​Operator​​进行优化操作,能进行合并的​​Operator​​会被合并为一个​​Operator​​,合并后的​​Operator​​称为​​Operator chain​​,实际上就是一个执行链,每个执行链会在​​TaskManager​​上一个独立的线程中执行–就是​​SubTask​​。

4.4 任务槽与槽共享

4.4.1 任务槽(TaskSlot)

Flink教程(05)- Flink原理简单分析_插槽_07

每个​TaskManager​是一个​​JVM​​的进程,为了控制一个​​TaskManager(worker)​​能接收多少个​​task​​,​​Flink​​通过​​Task Slot​​来进行控制。

  • ​TaskSlot​​​数量是用来限制一个​​TaskManager​​工作进程中可以同时运行多少个工作线程;
  • ​TaskSlot​​​是一个​​TaskManager​​ 中的最小资源分配单位;
  • 一个​​TaskManager​​​中有多少个​​TaskSlot​​​就意味着能支持多少并发的​​Task​​处理。

Flink​将进程的内存进行了划分到多个​​slot​​​中,内存被划分到不同的​​slot​​之后可以获得如下好处:

  • ​TaskManager​​​最多能同时并发执行的子任务数是可以通过​​TaskSolt​​数量来控制的;
  • ​TaskSolt​​​有独占的内存空间,这样在一个​​TaskManager​​中可以运行多个不同的作业,作业之间不受影响。

4.4.2 槽共享(Slot Sharing)

Flink教程(05)- Flink原理简单分析_flink_08

​Flink​​允许子任务共享插槽,即使它们是不同任务(阶段)的子任务(​​subTask​​),只要它们来自同一个作业。

比如上图图左下角中的​​map​​​和​​keyBy​​​和​​sink​​​ 在一个 ​​TaskSlot​​里执行以达到资源共享的目的。

允许插槽共享有两个主要好处​:

  • 资源分配更加公平,如果有比较空闲的​​slot​​可以将更多的任务分配给它;
  • 有了任务槽共享,可以提高资源的利用率。

注意:

  • ​slot​​​是静态的概念,是指​​taskmanager​​具有的并发执行能力;
  • ​parallelism​​是动态的概念,是指程序运行时实际使用的并发能力。

05 Flink运行时组件

Flink教程(05)- Flink原理简单分析_hadoop_09

Flink​运行时架构主要包括四个不同的组件,它们会在运行流处理应用程序时协同工作:

  • 作业管理器(JobManager)​:分配任务、调度​​checkpoint​​做快照
  • 任务管理器(TaskManager)​:主要干活的
  • 资源管理器(ResourceManager)​:管理分配资源
  • 分发器(Dispatcher​):方便递交任务的接口,​​WebUI​

因为​​Flink​​​是用​​Java​​​和​​Scala​​​实现的,所以所有组件都会运行在​​Java​​虚拟机上,每个组件的职责如下:

5.1 作业管理器(JobManager)

  • 控制一个应用程序执行的主进程,也就是说,每个应用程序都会被一个不同的​​JobManager​​ 所控制执行。
  • ​JobManage​​​r 会先接收到要执行的应用程序,这个应用程序会包括:作业图(​​JobGraph​​​)、逻辑数据流图(​​logical dataflow graph​​​)和打包了所有的类、库和其它资源的​​JAR​​包;
  • ​JobManager​​​ 会把​​JobGraph​​​转换成一个物理层面的数据流图,这个图被叫做“执行图”(​​ExecutionGraph​​),包含了所有可以并发执行的任务;
  • ​JobManager​​​会向资源管理器(​​ResourceManager​​​)请求执行任务必要的资源,也就是任务管理器(​​TaskManager​​​)上的插槽(​​slot​​​),一旦它获取到了足够的资源,就会将执行图分发到真正运行它们的​​TaskManager​​​上,而在运行过程中,​​JobManager​​​会负责所有需要中央协调的操作,比如说检查点(​​checkpoints​​)的协调。

5.2 任务管理器(TaskManager)

  • ​Flink​​​中的工作进程,通常在​​Flink​​​中会有多个​​TaskManager​​​运行,每一个​​TaskManager​​​都包含了一定数量的插槽(​​slots​​​)。插槽的数量限制了​​TaskManager​​能够执行的任务数量。
  • 启动之后,​​TaskManager​​​会向资源管理器注册它的插槽;收到资源管理器的指令后,​​TaskManager​​​就会将一个或者多个插槽提供给​​JobManager​​​调用。​​JobManager​​​就可以向插槽分配任务(​​tasks​​)来执行了。
  • 在执行过程中,一个​​TaskManager​​​可以跟其它运行同一应用程序的​​TaskManager​​交换数据。

5.3 资源管理器(ResourceManager)

  • 主要负责管理任务管理器(​​TaskManager​​​)的插槽(​​slot​​​),​​TaskManger​​​ 插槽是​​Flink​​中定义的处理资源单元。
  • ​Flink​​​为不同的环境和资源管理工具提供了不同资源管理器,比如​​YARN​​​、​​Mesos​​​、​​K8s​​​,以及​​standalone​​部署。
  • 当​​JobManager​​​申请插槽资源时,​​ResourceManager​​​会将有空闲插槽的​​TaskManager​​​分配给​​JobManager​​​。如果​​ResourceManager​​​没有足够的插槽来满足​​JobManager​​​的请求,它还可以向资源提供平台发起会话,以提供启动​​TaskManager​​进程的容器。

5.4 分发器(Dispatcher)

  • 可以跨作业运行,它为应用提交提供了​​REST​​接口;
  • 当一个应用被提交执行时,分发器就会启动并将应用移交给一个​​JobManager​​;
  • ​Dispatcher​​​也会启动一个​​Web UI​​,用来方便地展示和监控作业执行的信息;
  • ​Dispatcher​​在架构中可能并不是必需的,这取决于应用提交运行的方式。

06 Flink执行图(ExecutionGraph)

由​​Flink​​​程序直接映射成的数据流图是​​StreamGraph​​​,也被称为逻辑流图,因为它们表示的是计算逻辑的高级视图,为了执行一个流处理程序,​​Flink​​需要将逻辑流图转换为物理数据流图(也叫执行图),详细说明程序的执行方式。

​Flink​​ 中的执行图可以分成四层:​​StreamGraph -> JobGraph -> ExecutionGraph -> 物理执行图​​:

Flink教程(05)- Flink原理简单分析_flink_10

6.1 原理

​Flink​​​执行​​executor​​​会自动根据程序代码生成​​DAG​​数据流图;

​Flink​​ 中的执行图可以分成四层:​​StreamGraph -> JobGraph -> ExecutionGraph -> 物理执行图​​:

  • StreamGraph :是根据用户通过​​Stream API​​编写的代码生成的最初的图,表示程序的​拓扑结构​。
  • JobGraph :​​StreamGraph​​​经过优化后生成了​​JobGraph​​​,提交给​​JobManager​​​的数据结构。主要的优化为,将多个符合条件的节点​​chain​​在一起作为一个节点,这样可以减少数据在节点之间流动所需要的序列化/反序列化/传输消耗。
  • ExecutionGraph :​​JobManager​​​根据​​JobGraph​​​生成​​ExecutionGraph​​​。​​ExecutionGraph​​​是​​JobGraph​​的并行化版本,是调度层最核心的数据结构。
  • 物理执行图 :​​JobManager​​​ 根据​​ExecutionGraph​​​ 对​​Job​​​进行调度后,在各个​​TaskManager​​​ 上部署​​Task​​后形成的“图”,并不是一个具体的数据结构。

可以简单理解为:

  • StreamGraph​:最初的程序执行逻辑流程,也就是算子之间的前后顺序–在​​Client​​上生成;
  • JobGraph​:将​​OneToOne​​​的​​Operator​​​合并为​​OperatorChain​​​–在​​Client​​上生成
  • ExecutionGraph​:将​​JobGraph​​​根据代码中设置的并行度和请求的资源进行并行化规划!–在​​JobManager​​上生成
  • 物理执行图​:将​​ExecutionGraph​​​的并行计划,落实到具体的​​TaskManager​​​上,将具体的​​SubTask​​​落实到具体的​​TaskSlot​​内进行运行。