Flink流式计算模型

 

flink operator session模式 flink的operator_数据

图中的stream为传输通道中的数据,operator为flink中的算子,Source为数据源,sink是最终处理的数据去向。流式计算模型中由计算节点的多个并行实例组成,其中并行实例的含义是:在分布式环境中,同一计算节点有多个功能相同的的物理部署实例,。其并行模式图可参考下图。

flink operator session模式 flink的operator_并行度_02

在并行任务时候,每个operator的实例数为并行度,任意两个operator的并行度之间是独立的,每个operator也就是算子称为一个任务,而operator的每个实例称为算子的子任务(subtask);Stream有一个或多个分区(partition)Stream有两种连接模式:直连(one-to-one)模式,即一个实例的输出是另一个实例的输入,在图中source的子任务source【1】和map的子任务map[1]就是直连的;分区(Redistribution)模式,即一个实例的输出被拆分成多个部分传输给不同的下流实例,比如:图中map【1】处理的数据就被拆成两部分,分别传给下流实例。

流处理编程可参考我的上一篇博客,里面测试了一些常用的flink Api。

Flink运行时结构

运行状态图:

 

 

flink operator session模式 flink的operator_运行时架构_03

流程:

1、Program Code:我们编写的 Flink 应用程序代码

2、Job Client:Job Client 不是 Flink 程序执行的内部部分,但它是任务执行的起点。 Job Client 负责接受用户的程序代码,然后创建数据流,将数据流提交给 Job Manager 以便进一步执行。 执行完成后,Job Client 将结果返回给用户

3、Job Manager:主进程(也称为作业管理器)协调和管理程序的执行。 它的主要职责包括安排任务,管理checkpoint ,故障恢复等。机器集群中至少要有一个 master,master 负责调度 task,协调 checkpoints 和容灾,高可用设置的话可以有多个 master,但要保证一个是 leader, 其他是 standby; Job Manager 包含 Actor system、Scheduler、Check pointing 三个重要的组件

4、Task Manager:从 Job Manager 处接收需要部署的 Task。Task Manager 是在 JVM 中的一个或多个线程中执行任务的工作节点。 任务执行的并行性由每个 Task Manager 上可用的任务槽决定。 每个任务代表分配给任务槽的一组资源。

 

 

flink operator session模式 flink的operator_并行度_04

为了高效的分布式执行,flink会尽可能传递将operator的subtask连接在一起形成task,上图中将key Aggregation和sink连个operator进行了合并,因为这两个合并之后并不会改变整体的拓扑结构。operator chain的优点:减少线程切换,减少序列化与反序列化,减少数据在缓冲区的交换,减少延迟,并提高吞吐量,构成operator chain 的条件:1.没有禁用chain,上下游算子并行度一致,2.下游算子的入度为1(也就是说下游节点没有来自其它节点的输入),3.上下游算子在同一个slot group(默认情况下一个job的slot group都在一个slot group下,但可以通过编程更改见下文),4.下游节点的chain策略为always(可以与上下游连接,map,flat map,fliter等默认是always),5.上游节点的chain策略为always或者HEAD(只能与下游连接,不能与上游连接,source默认是HEAD),6.上下游算子之间没有数据shuffle(数据分区方式是forward)。

编程更改operator chain

可以通过在DataStream的operator后面(如someStream.map(...))调用startNewChain()来指示从该operator开始一个新的chain(与前面截断,不会被chain到前面);调用disableChaining()来指示该operator不参与chaining(不会与前面的operator chain在一起);通过调用StreamExecutionEnvironment.disableOperatorChainning(禁用全局chaining);设置slot group 例如,someStream.filter(..).slotSharingGroup("name"),调整并行度。

默认情况下,Flink允许subtasks共享slot,条件是他们都来自同一个job的不同task的subtask,结果可能一个slot持有该job的整个pipeline,允许slot共享有以下两点好处:

    flink集群需要的任务槽与作业中的使用的最高并行度正好相同,即不需要计算一个程序会起多少个task了,更容易获得充分的资源利用。

线程共享slot

为了控制执行的任务数量,Taskmanager将计算资源划分为多个slot,每个slot独享给其分配的计算资源,这种静态的资源管理方式有利于任务间资源隔离,taskmanager可以将配置成单slot模式,这样这个worker上运行的任务就独占了整个JVM进程,同一个JVM进程上的多个任务可以共享TCP连接,心跳和数据。 Task Manager 的一个 Slot 代表一个可用线程,该线程具有固定的内存,注意 Slot 只对内存隔离,没有对 CPU 隔离。默认情况下,Flink 允许子任务共享 Slot,即使它们是不同 task 的 subtask,只要它们来自相同的 job。这种共享可以有更好的资源利用率。

flink operator session模式 flink的operator_运行时架构_05

SlotSharingGroup是flink中用来实现slot共享的类,他尽可能的让subtasks共享一个slot槽位,保证同一个group的并行度相同的subtasks,共享同一个slots,算子默认group为default(即默认一个job下的subtask都可以共享一个slot),为了防止不合理的共享,用户也可以通过api来强制指定operator的共享组,比如somestream.fliter(..).slotSharingGroup("group1"),就强制指定filter的slot共享组为group1。

colocationGroup强制并行度一样的subtask共享同一个slot。

注:

不设置slotSharingGroup(需要应用的最大并行度个slot)

设置slotSharingGroup(需要所有slotSharingGroup最大并行度之和个slot)

flink operator session模式 flink的operator_数据_06

 

总结:

slot是taskmanager的并发执行能力

parallism是指taskmanager实际使用的并发能力(可配置)