flink1.10版本StreamGraph生成过程分析

1、StreamGraph本质
本质就是按照用程序代码的执行顺序构建出来的用于向执行环境传输的流式图,并且可以支持可视化展示给用户的一种数据结构。
2、StreamGraph、StreamNode和StreamEdge的数据结构
StreamGraph构建DAG流图时,其核心是要维护好节点及节点之间的关系即可,关于这块主要是以下关键属性:

而节点之间的关系是由节点自身数据结构来维护的,在StreamNode包含着节点和上下游节点间的关系:

节点关系的具体表征就是StreamEdge了:

以上三个类除了维护构建DAG流图相关属性外,还包含了其他与流程序执行相关的属性以及一些其他参数,如输入输出序列化、格式化等等。
3、构建入口

从StreamExecutionEnvironment环境中构建StreamGraph时分成两个部分:
首先从全局执行环境参数中构建出一个StreamGraphGenerator对象,并将部分全局参数设置进去;
然后再由这个StreamGraphGenerator对象去generat出StreamGraph
3、构建过程

构建过程又可以分为两个步骤:
首先new一个StreamGraph对象,并且设置其全局的一些config参数:
然后对其中的每一个transform算子进行循环递归处理,组织其内部的Node与Edge关系,形成最终结果:
单个算子的处理时,根据每个算子的类型有其单独的算法

4、Transformation抽象类的体系结构
这里没有定义为接口而是一个抽象类,猜测设计这个类的初衷是提取公共属性而非提取transform的模板方法了,否则也不会有上面那一大坨分类处理的ifelse

5、transform算子具体逻辑
transform算子的套路额基本相差不大,都是由transformXXX方法完成,大概都包含以下步骤:
a、包含input时先递归处理上游算子;
b、通过一个hashmap的缓冲池检验是否已经处理过,避免重复处理
c、选择slot共享算法
d、生成StreamNode并加入StreamGraph
e、设置输入输出序列化方式、格式化类型等规则
f、设置算子并行度
g、生成StreamEdge,维护正确的上下游关系
其中如果有多输入或者虚拟节点时,根据具体规则进行节点的拆分重组,然后再递归调用即可,下面看各类型节点的具体处理规则
OneInputTransformation<IN, OUT>

TwoInputTransformation<IN1, IN2, OUT>

SourceTransformation:source节点没有上游节点了,其边的关系由他的下游节点维护即可

SinkTransformation

UnionTransformation:union时,只需维护好上下游的关系即可,正确连接起来

SplitTransformation:split则拆分出两个OutputSelector

SelectTransformation:select当做虚拟算子处理

FeedbackTransformation:feedback比较特殊,形成新类似的source/sink节点对,需要再次分别处理

CoFeedbackTransformation:对比参考FeedbackTransformation
PartitionTransformation:partition也是作为一类虚拟节点来处理,

SideOutputTransformation:类似partition

6、StreamGraph的addSink、addSource以及addOperator、addEdge方法
在transform各类算子时,其实在构建流图时最核心的方法是调用了addOperator和addEdge方法;
addSink和addSource其实是调用了addOperator,同时存储了对应的编码

而addOperator则是调用了addNode方法来添加Node,顺便再次补充设置输入输出的序列化方法和格式化类型

最后来看addNode方法,此处才是真正生成Node并且加入图的方法

addEdge就比较简单了,直接调用addEdgeInternal方法,在addEdgeInternal方法类进行分类处理,如果是虚拟节点就按照对应规则进行拆分重组然后再递归调用,如果是普通节点就构建关系衔接起来即可

至此,整个由StreamExecutionEnvironment中生成StreamGraph的全过程,尤其是构建流图的核心逻辑解析完了
7、最后补充一个点
在StreamExecutionEnvironment中的transforms集合中其实是没有存储source算子的,是由source算子的下游往前找input时补充回去的,看运行时的代码:


对比即可发现,同时在StreamExecutionEnvironment的addSource方法中是没有添加operator操作的

Tags: