目录

JobGraph的详细构成

JobVertex

 Intermediate DataSet

JobEdge


JobGraph和StreamGraph最重要的区别就是:对满足chainable条件的算子进行了chain!

StreamGraph 经过优化后生成了 JobGraph,提交给 JobManager 的数据结构。 主要的优化为:将多个符合条件的节点 chain 在一起作为一个节点,这样可以减少数据在节 点之间流动所需要的序列化/反序列化/传输消耗。

JobGraph也是在client端生成的,我们看一下StreamGraph->JobGraph的变化:

flink面试题目 flink jobgraph_flink

主要的变化有:

  • StreamNode变成了JobVertex
  • StreamEdge变成了JobEdge
  • 增加了IntermediateDataSet
  • Forward相连的StreamNode合并(chain)成一个JobVertex

JobGraph的详细构成

同样,我们进入debug模式,从execute()方法一路点点点,到了 StreamingJobGraphGenerator.createJobGraph()方法。

JobVertex

查看jobGraph对象中的taskVertices变量,该field是一个LinkedHashMap,key是JobVertexID value是JobVertex对象。

flink面试题目 flink jobgraph_java_02

思考:为什么这个LinkedHashMap里面value的顺序是从sink到source,跟正常的data流向是反着的呢?

 Intermediate DataSet 和 JobEdge在哪里呢?就在JobVertex中(以FlatMapSplit算子为例):

flink面试题目 flink jobgraph_1024程序员节_03

JobVertex中有两个field:results,inputs都是ArrayList,对应了该算子的ouput和input。

让我们针对该算子画一个简单的图:

flink面试题目 flink jobgraph_flink面试题目_04

 Intermediate DataSet

以FlatMapSplit算子为例:

flink面试题目 flink jobgraph_flink_05

  • producer:上游,在这里是JobVertex类型
  • consumer:下游,在这里是JobEdge的List
  • ResultPartitionType:指定了 ResultPartition 的不同属性,这些属性包括是否流水线模式、是否会产生反压以及是否限制使用的 Network buffer 的数量。ResultPartitionType 有三个枚举值:
  • BLOCKING:非流水线模式,无反压,不限制使用的网络缓冲的数量
  • PIPELINED:流水线模式,有反压,不限制使用的网络缓冲的数量
  • PIPELINED_BOUNDED:流水线模式,有反压,限制使用的网络缓冲的数量
    其中是否流水线模式这个属性会对消费行为产生很大的影响:如果是流水线模式,那么在 ResultPartition 接收到第一个 Buffer 时,消费者任务就可以进行准备消费;而如果非流水线模式,那么消费者将等到生产端任务生产完数据之后才进行消费。目前在 Stream 模式下使用的类型是 PIPELINED_BOUNDED。

思考:为什么要多出Intermediate DataSet这一步呢?直接在Edge里面也可以啊?

JobEdge

flink面试题目 flink jobgraph_java_06

同样,对于JobEdge来说,输入和输出叫做:source 和 target。另外,还有几个有意思的参数:

  • DistributionPattern: Enum类型, ALL_TO_ALL 和 POINTWISE 定义了上下游之间数据分发的方式
  • SubtaskStateMapper:Enum类型,跟数据回放有关
  • shipStrategyName: ShipStrategyType 类型: 
public enum ShipStrategyType {   

   NONE(false, false), //没有策略
   FORWARD(false, false), //数据按原分区号传递到本地运行的Task相同分区,不跨网络,不需要比较器(用于排序或Hash)
   PARTITION_RANDOM(true, false),//数据随机传递到本地运行的Task任意分区,不跨网络,不需要比较器
   PARTITION_HASH(true, true),//数据按照指定键值的Hash决定分区,到目标Task需要跨网络传递,需要比较器
   PARTITION_RANGE(true, true),//数据按照指定键值的排序顺序决定分区,到目标Task需要跨网络传递,需要比较器  
  BROADCAST(true, false) // 将数据复制到任意一个分区中,不需要比较器
   PARTITION_FORCED_REBALANCE(true, false), // 将数据平均到各个分区中,不需要比较器
   PARTITION_CUSTOM(true, true); // 将数据按用户指定的分区器分配分区,不需要比较器
...
}

StreamGraph 到 JobGraph的转化过程其实是做了很多的优化的。我们后续会慢慢展开。