Flink运行时之生成作业图

生成作业图

在分析完了流处理程序生成的流图(StreamGraph)以及批处理程序生成的优化后的计划(OptimizedPlan)之后,下一步就是生成它们面向Flink运行时执行引擎的共同抽象——作业图(JobGraph)。

什么是作业图

作业图(JobGraph)是唯一被Flink的数据流引擎所识别的表述作业的数据结构,也正是这一共同的抽象体现了流处理和批处理在运行时的统一。

相比流图(StreamGraph)以及批处理优化计划(OptimizedPlan),JobGraph发生了一些变化,已经不完全是“静态”的数据结构了,因为它加入了中间结果集(IntermediateDataSet)这一“动态”概念。

作业顶点(JobVertex)、中间数据集(IntermediateDataSet)、作业边(JobEdge)是组成JobGraph的基本元素。这三个对象彼此之间互为依赖:

  • 一个JobVertex关联着若干个JobEdge作为输入端以及若干个IntermediateDataSet作为其生产的结果集;
  • 一个IntermediateDataSet关联着一个JobVertex作为生产者以及若干个JobEdge作为消费者;
  • 一个JobEdge关联着一个IntermediateDataSet可认为是源以及一个JobVertex可认为是目标消费者;

因此一个JobGraph可能的图形化表示如下:

JobGraph-visualization

那么JobGraph是怎么组织并存储这些元素的呢?其实JobGraph只以Map的形式存储了所有的JobVertex,键是JobVertexID:

private final Map<JobVertexID, JobVertex> taskVertices = new LinkedHashMap<JobVertexID, JobVertex>();

至于其它的元素,通过JobVertex都可以根据关系找寻到。

JobGraph包含了如下这些属性:

  • 描述作业相关的信息,比如上面的顶点、作业编号、名称等;
  • 用户程序包相关的信息,比如类路径等;
  • 执行的一些配置信息,比如异步快照的配置、会话超时、是否允许排队调度等;

绝大部分的实例方法都是维护这些属性的。

需要注意的是,用于迭代的反馈边(feedback edge)当前并不体现在JobGraph中,而是被内嵌在特殊的JobVertex中通过反馈信道(feedback channel)在它们之间建立关系。

流图生成作业图

这篇文章我们来分析流处理程序是如何从之前的Stream生成JobGraph的。这部分的实现位于类StreamingJobGraphGenerator中,它是流处理程序的JobGraph生成器,其核心是createJobGraph方法,它体现了生成JobGraph的主干调用,实现代码如下:

public JobGraph createJobGraph() {   
    //创建一个JobGraph实例对象
    jobGraph = new JobGraph(streamGraph.getJobName());   

    //设置对task的调度模式为ALL,即所有的算子立即同时启动
    jobGraph.setScheduleMode(ScheduleMode.ALL);   

    //对用于辅助生成JobGraph的一些实例变量进行初始化
    init();   

    //给StreamGraph的每个StreamNode生成一个hash值,该hash值在节点不发生改变的情况下多次生成始终是一致的,
    //可用来判断节点在多次提交时是否产生了变化并且该值也将作为JobVertex的ID
    Map<Integer, byte[]> hashes = traverseStreamGraphAndGenerateHashes();   

    //基于StreamGraph从所有的source开始构建task chain
    setChaining(hashes);   

    //给顶点设置物理边(入边)
    setPhysicalEdges();   

    //为每个JobVertex设置slotShareGroup,同时为迭代的source/sink对设置CoLocationGroup
    setSlotSharing();      

    //配置检查点
    configureCheckpointing();   

    //配置重启策略
    configureRestartStrategy();   

    //传递执行配置
    jobGraph.setExecutionConfig(streamGraph.getExecutionConfig());    

    return jobGraph;
}

接下来我们挨个对几个关键的方法进行分析。第一个要分析的方法是traverseStreamGraphAndGenerateHashes,它会对StreamGraph进行遍历并为每一个StreamNode都生成其哈希值,生成的哈希值将用于为每个JobVertex创建JobVertexID。方法的完整实现如下:

private Map<Integer, byte[]> traverseStreamGraphAndGenerateHashes() {
    //hash函数      
    final HashFunction hashFunction = Hashing.murmur3_128(0);   
    final Map<Integer, byte[]> hashes = new HashMap<>();   
    //存储访问过了的节点编号
    Set<Integer> visited = new HashSet<>();   
    //入队即将访问的节点对象
    Queue<StreamNode> remaining = new ArrayDeque<>();   

    //source是一个流拓扑的起点,从source开始遍历
    //hash值的生成是顺序敏感的(依赖于顺序),因此首先要对source ID集合进行排序
    
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值