目录
JobGraph的详细构成
JobVertex
Intermediate DataSet
JobEdge
JobGraph和StreamGraph最重要的区别就是:对满足chainable条件的算子进行了chain!
StreamGraph 经过优化后生成了 JobGraph,提交给 JobManager 的数据结构。 主要的优化为:将多个符合条件的节点 chain 在一起作为一个节点,这样可以减少数据在节 点之间流动所需要的序列化/反序列化/传输消耗。
JobGraph也是在client端生成的,我们看一下StreamGraph->JobGraph的变化:
主要的变化有:
- StreamNode变成了JobVertex
- StreamEdge变成了JobEdge
- 增加了IntermediateDataSet
- Forward相连的StreamNode合并(chain)成一个JobVertex
JobGraph的详细构成
同样,我们进入debug模式,从execute()方法一路点点点,到了 StreamingJobGraphGenerator.createJobGraph()方法。
JobVertex
查看jobGraph对象中的taskVertices变量,该field是一个LinkedHashMap,key是JobVertexID value是JobVertex对象。
思考:为什么这个LinkedHashMap里面value的顺序是从sink到source,跟正常的data流向是反着的呢?
Intermediate DataSet 和 JobEdge在哪里呢?就在JobVertex中(以FlatMapSplit算子为例):
JobVertex中有两个field:results,inputs都是ArrayList,对应了该算子的ouput和input。
让我们针对该算子画一个简单的图:
Intermediate DataSet
以FlatMapSplit算子为例:
- producer:上游,在这里是JobVertex类型
- consumer:下游,在这里是JobEdge的List
- ResultPartitionType:指定了 ResultPartition 的不同属性,这些属性包括是否流水线模式、是否会产生反压以及是否限制使用的 Network buffer 的数量。ResultPartitionType 有三个枚举值:
- BLOCKING:非流水线模式,无反压,不限制使用的网络缓冲的数量
- PIPELINED:流水线模式,有反压,不限制使用的网络缓冲的数量
- PIPELINED_BOUNDED:流水线模式,有反压,限制使用的网络缓冲的数量
其中是否流水线模式这个属性会对消费行为产生很大的影响:如果是流水线模式,那么在 ResultPartition 接收到第一个 Buffer 时,消费者任务就可以进行准备消费;而如果非流水线模式,那么消费者将等到生产端任务生产完数据之后才进行消费。目前在 Stream 模式下使用的类型是 PIPELINED_BOUNDED。
思考:为什么要多出Intermediate DataSet这一步呢?直接在Edge里面也可以啊?
JobEdge
同样,对于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的转化过程其实是做了很多的优化的。我们后续会慢慢展开。