这是我参与「第四届青训营 」笔记创作活动的第2天
Flink引擎介绍
Flink概述
批计算: 离线计算,静态的数据集等待一批数据(时/天为单位)
流计算: 实时计算,动态无边界,低延迟(毫秒级)
Flink 是一个 集流处理与批处理于一体的框架、分布式处理引擎,对有界和无界数据流进行状态计算
Flink架构原理
Flink 是一个分布式系统, 需要有效分配和管理计算资源才能执行流应用程序 。它集成了所有常见的集群资源管理器,例如Hadoop、YARN,但也可以设置作为独立集群甚至库运行。
下面的图是Flink的架构, Flink 运行时由两种类型的进程组成:一个 JobManager 和一个或者多个 TaskManager 。
JobManager
JobManager主要是来协调Flink分布式执行的相关操作,
JobManager 决定何时调度下一个 task(或一组 task)、对完成的 task 或执行失败做出反应、协调 checkpoint、并且协调从失败中恢复 等等。
- ResourceManager: Flink的资源调度单位,管理 task slots 。在 standalone 设置中,ResourceManager 只能分配可用 TaskManager 的 slots,而不能自行启动新的 TaskManager。
- Dispatcher: 提供了一个 REST 接口,用来提交 Flink 应用程序执行,并为每个提交的作业启动一个新的 JobMaster。同时还运行一个webUI来显示作业的执行信息
- JobMaster: 管理单个的 JobGraph 执行,每个Job都有自己的JobMaster
在Flink集群中至少有一个JobManager,在多个JobManager的情况下保证只有一个Leader
TaskManager
可以理解为工作者, 执行作业流的 task,并且缓存和交换数据流 。
保证始终至少有一个TaskManager,其最小的资源调度单位是task slot,但一个task slot中可以执行多个算子。
作业执行流程
Flink 程序本质上是分布式并行程序。在程序执行期间,一个流有一个或多个流分区(Stream Partition),每个算子有一个或多个算子子任务(Operator Subtask)。每个子任务彼此独立,并在不同的线程中运行,或在不同的计算机或容器中运行。
算子传输数据模式
一对一模式: 保留元素的分区和顺序信息,同一分区的数据只会进入到下游算子的同一分区。如上图中Source和map()之间的关系。
重新分发模式: 会更改数据所在的流分区,使用不同的 transformation,每个算子子任务也会根据不同的 transformation 将数据发送到不同的目标子任务。如上图中 map()和 keyBY()/window()、keyBY()/window()和Sink之间的关系。在重新分发数据的过程中,元素只有在每对输出和输入子任务之间才能保留其之间的顺序信息。
常见的 transformation 和其对应的分发模式: keyBy() (通过散列键重新分区)、broadcast() (广播)或 rebalance() (随机重新分发)
算子链
Flink 将算子的 subtasks 链接成 tasks。每个 task 由一个线程执行。将算子链接成 task 是个有用的优化:它减少线程间切换、缓冲的开销,并且减少延迟的同时增加整体吞吐量。如上图中 将Source和map链在一起 的优化。
Task Slots
每个TaskManager都是一个JVM,在单独的县城中可以执行一个或多个的subtask。Task Slots的出现便是 为了让一个TM能够接受多个Task 。
slot代表TaskManager中的固定子集,每个TaskManager中至少要有一个slot。一个slot只能运行一个task的subTask。
Flink的 流/批/OLAP 一体
Flink认为所有的都可以是流数据,批计算是流计算特殊的一种,OLAP计算是批计算特殊的一种。如此从API到底层的处理机制,任何一种数据可以使用统一的处理机制。
Flink支持流/批一体
- SQL层
- DataStream API层统一
- Scheduler层架构统一: 主要将作业的DAG转化为可执行的Task
- Failover Recovery层架构统一
- Shuffle Service层架构统一: 连接上下游数据交互