详细分析了Flink的运行架构。
1. Flink 程序结构
Flink程序的基本构造块是流和转换(请注意,Flink的DataSet API中使用的数据集也是内部流)。从概念上讲,流是数据记录的(可能是永无止境的)流,而转换是将一个或多个流作为一个或多个流的操作。输入并生成一个或多个输出流。
Flink应用程序结构如上图所示:
Source:数据源,Flink在流处理和批处理中的源码可以分为四类:基于本地采集的源码、基于文件的源码、基于网络套接字的源码和用户自定义源码。常用的自定义源码有Apache kafka、RabbitMQ等。当然,你也可以定义自己的来源。
Transformation:有各种各样的数据转换操作,比如地图/平面图/过滤器/key by/reduce/fold/aggregation/window all/union/windowjoin/split/select等。有很多操作,可以把数据转换成你想要的数据。
Sink:接收器,弗林克将发送转换和计算数据的地方,你可能需要存储它。Flink常见的接收器包括以下几类:写文件、打印输出、写套接字和用户定义的接收器。常用的定制接收器有Apache kafka、RabbitMQ、MySQL、ElasticSearch、Apache Cassandra、Hadoop FileSystem等。同样,您也可以定义自己的水槽。
2. Flink 并行数据流
当Flink程序执行时,它将被映射到一个流数据流中,该数据流由一组流和转换运算符组成。以一个或多个源运算符开始,以一个或多个接收器运算符结束。
Flink 程序本质上是并行的和分布式的,在执行过程中,一个流包含一个或多个流分区,而每个操作符包含一个或多个操作子任务。子任务相互独立,在不同的线程中执行,甚至在不同的机器或容器上执行。运算符子任务的数量是该特定运算符的并行度。同一程序中不同的运算符具有不同的并行度。
一个流可以分成多个流分区,即流分区。一个操作员也可以分成多个操作员子任务。在上图中,Source分为Source1和Source2,分别是Source的运算符子任务。每个操作员子任务在不同的线程中独立执行。运算符的并行度等于运算符子任务的数量。上图中Source的并行度为2。流的并行度等于它生成的运算符的并行度。
在两个操作员之间传输数据有两种模式:
One to One 模式:当两个操作员在这种模式下转移时,他们将保持分区的数量和数据的顺序。从上图中的Source1到Map1,保留了Source的分区特性和处理分区元素的顺序。
Redistributing (重新分配)模式:这种模式将改变数据分区的数量;每个操作子任务都会根据所选的转换将数据发送到不同的目标子任务,比如keyBy()会通过hashcode进行重新分区,broadcast()和rebalance()方法会随机进行重新分区;
3. Task 和 Operator chain
弗林克的所有操作都被称为操作员。提交任务时,客户端将优化操作员。可以合并的运算符将合并为一个运算符。合并后的运算符称为运算符链,它实际上是一个执行链。每个执行链将在任务管理器的一个独立线程中执行。
4. 任务调度与执行
Flink执行执行器时,会根据程序代码自动生成DAG数据流图。
ActorSystem创建Actor,将数据流图发送给作业管理器。
中的 Actor;
JobManager 会不断接收 TaskManager 的心跳消息,从而可以获取到有效的 TaskManager;
JobManager 通过调度器在 TaskManager 中调度执行 Task(在 Flink 中,最小的调度单元就是 task,对应就是一个线程);
在程序运行过程中,task 与 task 之间是可以进行数据传输的。
Job Client:
- 主要职责是提交任务, 提交后可以结束进程, 也可以等待结果返回;
- Job Client 不是 Flink 程序执行的内部部分,但它是任务执行的起点;
- Job Client 负责接受用户的程序代码,然后创建数据流,将数据流提交给 Job Manager 以便进一步执行。 执行完成后,Job Client 将结果返回给用户。
JobManager:
- 主要职责是调度工作并协调任务做检查点;
- 集群中至少要有一个 master,master 负责调度 task,协调 checkpoints 和容错;
- 高可用设置的话可以有多个 master,但要保证一个是 leader, 其他是 standby;
- Job Manager 包含 Actor System、Scheduler、CheckPoint 三个重要的组件;
- JobManager 从客户端接收到任务以后, 首先生成优化过的执行计划, 再调度到 TaskManager 中执行。
TaskManager:
- 主要职责是从 JobManager 处接收任务, 并部署和启动任务, 接收上游的数据并处理;
- Task Manager 是在 JVM 中的一个或多个线程中执行任务的工作节点;
- TaskManager 在创建之初就设置好了 Slot, 每个 Slot 可以执行一个任务。
5. 任务槽和槽共享
每个 TaskManager 是一个 JVM 的进程, 可以在不同的线程中执行一个或多个子任务。
为了控制一个 worker 能接收多少个 task。worker 通过 task slot 来进行控制(一个 worker 至少有一个 task slot)。
1) 任务槽
每个 task slot 表示 TaskManager 拥有资源的一个固定大小的子集。
flink 将进程的内存进行了划分到多个 slot 中。
图中有 2 个 TaskManager,每个 TaskManager 有 3 个 slot 的,每个 slot 占有 1/3 的内存。
内存被划分到不同的 slot 之后可以获得如下好处:
-
TaskManager 最多能同时并发执行的任务是可以控制的,那就是 3 个,因为不能超过 slot 的数量。
-
slot 有独占的内存空间,这样在一个 TaskManager 中可以运行多个不同的作业,作业之间不受影响。
2) 槽共享
默认情况下,Flink 允许子任务共享插槽,即使它们是不同任务的子任务,只要它们来自同一个作业。结果是一个槽可以保存作业的整个管道。允许插槽共享有两个主要好处:
-
只需计算 Job 中最高并行度(parallelism)的 task slot,只要这个满足,其他的 job 也都能满足。
-
资源分配更加公平,如果有比较空闲的 slot 可以将更多的任务分配给它。图中若没有任务槽共享,负载不高的 Source/Map 等 subtask 将会占据许多资源,而负载较高的窗口 subtask 则会缺乏资源。
-
有了任务槽共享,可以将基本并行度(base parallelism)从 2 提升到 6.提高了分槽资源的利用率。同时它还可以保障 TaskManager 给 subtask 的分配的 slot 方案更加公平。
本文来自微信公众号:五分钟学大数据,转载请在公众号后台获取作者微信进行授权
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/67487.html