1.前言
截止到目前为止,基本上所有与FLink 中DateStream API相关的内容都介绍完毕了,如果你一直看到这里证明很多东西你都已经理解了。我在表述的过程中也是一直用的最基本的话语去进行描述的,相信读起来也并不费力。这篇文章可以说的上是这一部分知识的一个分水岭,因为在讲完了所有的重要概念之后,就要进入到Flink SQL的讲述阶段了,所以希望你可以认真看,且看且珍惜。
2.重要概念
2.1 数据流图(dataflow graph)
flink本身实际上就是对实时的数据进行计算处理的一个框架,它所做的就是每来一条数据,就要让这条数据按照规定好的执行流程计算一次,多个能进行数据处理的算子组合在一起就形成了一个能够让数据按流程处理的算子管道。在这个管道中,会按照对处理处理功能不同的切割成为source、transformation、sink。它们三个就主要负责数据的读、算、写三个阶段。
当作业被提交之后,FLink程序就会按照编写好的代码逻辑,将整个计算过程映射成为一个具备所有算子的逻辑顺序图。这个图是个有序无环图,它由一个或多个source算子开始,经过转换算子的处理之后,再由一个或多个sink算子写出。
2.2 并行度
并行度在Flink中是一个重要的概念,在Flink进行数据处理的时候,会将不同的算子分配到不同的节点上进行计算,虽然这种做法对任务进行了均摊,但是性能提升还是有限的,因为算子与算子之间是有先后顺序的,一条数据必须依次执行才能完成计算。而在使用了并行度这个概念之后,FLink会把一个算子任务按照并行度的数量在多个节点进行复制,数据来了之后就能够进入到任意一个节点上进行计算,这样也就把一个算子任务变成了多个算子任务,这些多个算子任务就叫做并行子任务,只要多个并行的子任务被分配到了不同的节点,那就是真正的实现了并行计算。而每一个算子的并行子任务个数,就是它的并行度。一个并行度就需要一个分区来进行处理,一个计算流程中算子的最大的并行度,就是这个计算流程的最大并行度。
在Flink中对并行度的设置有很多种方法,他们的优先级如下:
算子单独的并行度 > 代码全局并行度 > 提交时并行度 > 配置文件中并行度
2.3 算子链
在处理数据的过程中,可能会有很多算子的出现,这些算子对数据进行处理的时候可能会面临两种情况,第一种情况就是一对一模式,在这种模式下,元素的顺序是不会发生变化的,也不需要进行重新的分区。第二种情况就是重分区模式,数据的顺序会发生变化,分区也可能会发生变化。
在Flink中,并行度一对一的算子操作,可以直接链接起来形成一个大的任务,所有在这个任务里面的算子都变成了这个任务的一部分,这个任务会被一个线程执行,这个技术就是算子链。通过这个技术,可以十分有效的减少线程之间的切换和基于缓冲区之间的数据交换的时间。这种模式也可以通过代码显示禁用。
//禁用算子
.disableChaining();
//从当前算子开新链
.startNewChain()
2.4 图
图概念是FLink处理数据的时候一个很重要的概念,当代码被提交之后,首先要做的事情就是把代码映射成为逻辑流图,然后在逻辑流图的基础之上再进行变化,具体的变化过程如下:
逻辑流图-->作业图--->执行图--->物理图
1.逻辑流图
逻辑流图是通过api代码生成的最初的DAG图,用来标识程序的拓扑结构,这个步骤在客户端完成。
2.作业图
在逻辑流图的基础上进行优化,就得到了作业图,它确定了当前作业中所有任务的划分。主要的优化为: 将多个符合条件的节点链接在一起合并成一个任务节点,形成算子链,这样可以减少数据交换的消耗。JobGraph 一般也是在客户端生成的,在作业提交时传递给 JobMaster。
3.执行图
JobMaster 收到 JobGraph 后,会根据它来生成执行图(ExecutionGraph)。ExecutionGraph是 JobGraph 的并行化版本,是调度层最核心的数据结构。
4.物理图
JobMaster 生成执行图后, 会将它分发给 TaskManager;各个 TaskManager 会根据执行图部署任务,最终的物理执行过程也会形成一张“图”,一般就叫作物理图(Physical Graph)。这只是具体执行层面的图,并不是一个具体的数据结构。
2.5 任务槽和任务
任务槽solt是每一个TM上资源的一个子集,它是TM一组资源的封装。在现阶段,这种封装只限于内存的隔离,并不会涉及到CPU的隔离,可以在开发的过程中按照CPU线程的数量来设置solt的数量。在TM工作的时候,可以通过让TM开启并行度来实现多线程执行任务,这个TM能开启的线程数,就对应着它能够同时处理多少个并行子任务。如果一个TM能按照等量资源划分成为3个solt,那么两个TM就能够处理并行子任务数量总数小于等于6个的计算逻辑。但是一个TM划分出来的并行度越多,单一并行度的资源就越少,所以为了控制并发量,所以就需要通过任务槽的概念来帮助TM对每个任务运行的资源进行划分。
为了能够更好的运用集群的资源,任务还能够对任务槽进行共享。FLink中规定,面对同一计算任务,可以将不同的计算节点放置到相同的solt上执行,也就是说一个计算逻辑的最大并行度数量是不能够超过TM的任务槽数量的。因为一旦超过,多余的子任务就没有放置他们的资源了,这个时候就会进入等待状态。