00:00
那么接下来我们看一下咱们的作业图的一个生成,那么关于作业图呢,咱们,呃,首先第一点要知道它是在哪里完成的这个过程,怎么把在哪里把咱们的流图转成作业图,那么咱们之前做一个提交流程的时候,其实也看到了,那么归根结底是不是也是在客户端那一块完成的呀。对吧,啊,那这一块呢,生成一个作业图,这是第一个位置在哪个地方执行的,第二一个它主要做哪些事,那咱们关注啊,其实跟看这个图啊,他无非什么啊,首先第一个是不是可以。串在一起的,它串在一起的,这个是咱们第一个要呃知道的事情,做了这个事,第二个呢,是不是做了一些转换呢,把流节点转换成了。作业的一个图的一个顶点,对吧?啊,这是第二件事,那么第三件事是把这个边。
01:01
流边改成了一个作业的编啊,对吧,这是咱们要关注的另一个事,那还有一个是不是生成了一个中间数据集啊,哎,我们就关注这么几个事情啊,一个位置一个做的事啊。四个。好。那我们来找找啊,我们之前呢,是不是在执行用户代码CU之后找到的它呀,来我们看咱们这个类,呃,对吧,咱们cut经过层层调用,是不是来到了这啊,来到了这里,我们在这一行能够看到。他获取了一个作业图,好,那么接下来呢,咱们就一层一层找到它核心的执行逻辑啊,接下来是一个跳转的过程啊,那我们跳再进来之后,这一行又掉了一层再跳。
02:01
再往里点啊,又来到这里啊。再往里走。好,来到了一个接口啊,我们找实线,那么找实线很明显咱们是不是一个流图的转换器啊,啊在这里啊。好点进来搜这个方法。进来之后。又掉了一层对吧,流图get。一下job,我作业图啊,点那么点进来之后啊,终于我们在这个流图这个类里面,哎,找到了一个叫创建注意图的方法啊,再往里走。那么来到了一个流式的作业图生成器,在这里边有一个生成作业图的方法,那里边呢,它是利用了一个生成器之后呢,调用了一个一个create方法,那咱们接下来该进来看了,诶进来。啊,基本上就追到了这里啊,追到了这里,那么在这里面呢,做了什么事,我们先看一下啊。
03:05
那么首先呢,这边大家能看到一一个小细节,设置了一个调度的模式,那么关于这个调度模式啊,咱们在呃后面1.3.6小节里面会简单介绍一下有几种模式,那么目前呢,只要是流的执行模式,调度模式默认呢,是把所有节点一起去启动的啊,一起去提交启动,那么这个对应的名称叫这个。来给大家翻译一下。是不是渴望的急切的对吧,一下就等不了啊,一下子就都发出去了,都启动了啊一个啊。这个是模式啊,模式好,那么后面呢。我们往后看一些重要的,呃,是在。这一块啊,那其中最重要的就是set圈对吧,那这边就是咱们关注的怎么把节点转成顶点,怎么把边转成作业边,还有怎么把一些节点串在一起啊,那都在这个方法里头啊,Set training。
04:16
好,那么我们先来看这个东西,在圈里点进来。那么这个方法呢,主要啊,就是从咱们的S扇子开始,一步一步的往后把每一个节点也好编也好进行一个处理啊。那这边呢,是做了一个循环对不对,那循环每一个都会执行一个create。好,那这个里面呢。它就构建了一个节点链,另外呢,还有一个小细节,就物理的出边啊,就是它的出输出节点对应的这个出边它也有啊,也有封装进去,来我们具体看一看点。
05:02
看一下这啊,那这边呢,首先是创建了几个集合类型list对吧,List类型用来存放一些东西。那么这个分别是什么呢?这个是过渡的时候用的出边的几什么叫出边呢?对于我们一个顶点来讲,它往后的这条边是不是就叫粗边呢?对吧,这是过渡用的,那后面呢,这两个呢。啊,我们看名字就知道了。这个是不是可以串起来的出边呢?那这个叫不可以串的出边,对吧?那什么样叫可以串,什么叫不可以串呢?来我们看这。比如说这张图你看。这个节点后面的这个边,这个是不是它的出边呢。这一条边是不是可以串呢?为什么?因为这两个节点串起来,这个边是不是就没了啊,这这个边就叫可以串的边,那么像前面这种啊,这个边转到这个边,这种是属于什么。
06:09
不可以串的边对吧?啊,不可以串的边啊。好,那么我们往后走。那最终呢,是不是通过流图里边获取了一个。什么流节点对吧?哎,就是从头往前,咱们外面不是循环嘛,那最终不就是每个节点一个节点一个节点的处理嘛,好那么咱们现在拿取到一个当前流节点,好,那你看当前流节点它获取了什么。是不是它的出边呢?哎,它可能是不是有多个出边啊,可能的对吧。那么他,呃,对每个出边做了什么事啊,这个出边如果是可以串的,如果可以串他就放到这个。可以串到这个list里面,就前面new的这里啊,这好,那么S如果不能串,那就放到这个不能串的集合里面去啊,啊说白了,前面这一块是不是对边做一个分类存储啊,分类存储好再往下。
07:16
呃,那我们看这个是过渡用的边的集合,对吧,二二添加整个集合,你看它干嘛呢。是不是做了一个递归啊。对吧,这边是不是递归啊,并且。它是什么?这个索引是不是加一,就是后面一个对吧,后面一个在递归调用一遍,这个create change啊最终呢,反正就是递归调用完之后,是不是放到这里了。这个过度用的啊,过度用好再往下。如果是不能串的。哎,注意这个这个。过度用的集合存的是可串还是不可串呢?
08:03
可串的啊,过度用了这个存的是可串的啊,来后面是不可串的处理啊。哎,不可串的,它是不是也有一个临时用的。哎,不是他也得直接给加进来也是什么。是不是也是地归啊,所以这个里面包含了什么。可串的根。不可串的吧,但是它是不是分了一个类啊。就可串的放一起,不可串的放一起啊啊。啊,如果大家觉得啊,不知道他在干嘛,反正就是对边做了一个归类啊,做了一个归类,到目前为止,那中间会涉及到递归调用啊,递归调用什么叫递归啊。方法内部在调用自己这个方法对吧?哎,我们当前这个方法是不是就叫create China啊,然后它里面又调用了自己对吧?啊这递归嘛啊好再往下,那这些是生成一些显示信息对吧?这个打印的信息啊,那这些啊,咱们就不去看了。
09:07
这些在咱们的上下文可以打印出来,还记得吧?记得吧。就咱们在process的方法里边不是有个上下文吗?那我们那个上下文是不是可以get task内get sub task,那打印出来是不是就是这种格式,哎,有兴趣大家自己去打一下啊。就是这种格式的好,呃,那么往下看。往下看。这边做了什么,添加节点到链条里面,对吧,一个一个的往里添,它是不是先创建了一个,呃,在这个图里面慢慢的往里加呀,转弯放进来,转弯放进来,转弯放进来啊这样子。呃,创建容器,创建容器啊,不为空创建容器啊,这些不重要啊,来往下。
10:03
你看啊,当前的节点ID,比对一下是否是起始节点吧,就是不是S对吧,那么是不是三元表达式啊,如果是起始节点怎么样。这个方法名叫什么?是不是创建作业顶点啊,啊,其实就所以我们说这一步就是我们要看的一步,对吧,如果是SS,那我就把这个sources创建一个。作业顶点啊,作业的顶点啊。那如果没,如果不是呢。是不是创建一个叫stream config的对象?这个东西是啥呢?这个是用来存放作业顶点的,同学们啊,就是咱们转换好的作业顶点会放到这个里边。这个到时候后面呢,呃,作业图转发。给那个。执行图的时候会用到这个配置,他会去读啊,相当于说是一些信息在里面吧,配置信息啊配置信息。
11:03
好。你看设置配置,然后把一些信息啊,节点ID啊配置,还有它的可可串的出边,不可串的出边对吧,还有这个上游对吧。它的开头嘛,S嘛,就做了一些封装好,呃,再往下。诶,哪去了。啊,再往下到这里了啊,判断了一下当前节点是否是开始节点,那么大家其实看到前面也好,这里也好,是不是呃,都会做一个判断,当前节点是不是开头节点了,为什么要做这个判断呢?因为开头的话是比较特殊一点。对吧。开头它没有前面部分啊,啊,它没有前面部分啊。所以他就把开头标记为起始对吧,设置为起始啊,在配置文件里面指定啊,然后呢,再把它的索引号放进去,再把他的名字放进去,这都没啥,接下来。
12:08
将当前节点与所有的。出边相连啊,出边相连,那你看啊,那这里呢。出边它是先通过咱们的connect这个方法,把这个是流图的边啊,这是流图的边。然后呢,创建出作业的边。创建出作业的边,还有那个中间结果的生成。还有顶点跟边的一个连接值对应都在这个里,所以这个方法是不是很主很重要啊,Connect里面好,我们先知道,那后面呢,就是把这些弄完的边呢,放到这个配置里面对吧,还有把一些信息啊编啊等等其他信息都放到一个配置对象里面好。
13:01
那现在我们瞅一眼怎么转的啊点。这个方法里面干什么呢?是不是对边的转换呢,边的转换啊,我们往下看,往下看。你看是不是。我看看这边有什么啊。顶点,诶这边是不是获取了上一个顶点,还有下一个顶点,哎,再之后呢。下游顶点的配置,下游顶点下游点的配置对吧,下游顶点,然后呢,设置它的什么。下游的输入啊,什么意思啊,比如说这么现在两个点当前是不是处理这条边啊。当年处理这条边对不对,那这个就是下游的顶点是吧,那是不是算一下它前面有几条啊,对吧?啊就设设置一下前面有几条,呃,那获取一下分区器,再做一个类型的判断,看咱们是什么样的。
14:16
啊不这这啊对这个是分区器,那么再往后呢,对这个边获取了一下,它的杀补模式是基于pipeline还是P处理的,还是未定义的,对吧,那咱们应该是哪一个。是pipeline对吧。好拍line之后呢?没了吧,那接下来我们看作业边怎么生成的啊。作业边等于。下游流顶点。下游的顶点连接上。新的数据集当做一个输入啊。啊,当然这边呃。又是一堆的create,然后呃,反正最终咱们是怎么样。
15:02
是不是直接拧啊,对吧,拧出来的啊,那这个data set又从输入里边拿到的啊,输入是什么同学们。输入就是作业顶点啊。获取他的。结果啥意思啊?啥意思啊,同学们。就是这个边包含了,来我们再回忆一下这个边,它的上游输入是什么。是顶点吗?是顶点吗?咱们这中间是不是多了一个东西啊,中间数据集对吧?啊,假设这个叫编码,我标成红色的是不是中间数据集啊,那它的下游是什么。下游顶点对吧,说白了他new的时候做了什么事,是把它的输入传进来,把它的下游传进来啊,就封装进来,也就是说边保存了输入和输出的信息啊,啊说白了又在干这个事儿啊。
16:08
又在干这个事,你看还有添加他的消费者是当前这个边,是不是把这个前后绑定关系再次做一个绑定啊,对吧,中间结果它的下游是不是就是。边对不对,中间结果下游是不是边了。啊就啊,反正呢,大家知道这一回事就可以了啊,知道这回事儿就可以了。嗯。啊。那经过connect之后,咱们现在有什么了?是不是有这两个东西了。对吧,并且这边是不是也有做了一些连接关系啊,把作业顶点跟。出边这是粗边对吧。顶点的出边呢,啊,顶点后面的出边。
17:04
呃,连接好了,然后呢,把这些。呃,设置到配置里面,设置到配置里面。再往下我们看,如果这边指的是什么,前面这些逻辑是不是都是start的一个逻辑啊,就开头的节点了。是开头节点走这个,那么接下来这边是不是非开头啊。非开头的话,你看他做了什么啊。嗯。获取了一个流节点,对吧,然后呢。把名字设置一下,然后呢。把他信息加入到config里面。没了。就没了,就很简单啊,就很简单。这边大家觉得是不是很复杂。
18:01
啊,所以我我这边注释会多一点啊,多一点,那么如果大家对整个逻辑。呃,就感觉好麻烦,好费劲,那么你就把咱们标的这几个重,呃几个步骤,你知道这一步干嘛的,这一步干嘛的,这一步干嘛的也就可以了啊也就可以了。来,呃,我看看我这边有一段总结性的话啊,就是关于咱们这个可创建链条的这个方法。啊,这边有一段描述,咱们来一起读一下啊,对于每一个作业顶点都会对应一个可序列化的。String con,也就是说作业顶点是放到这个里面的啊,它对应的配置都在这里面。它是用来发送给。呃,其他组件啊,其他组件,那么最后在我们起task的时候,它就是从这里面这个对象是最conflict反序列化出来它需要的配置信息,所以大家在代码里面会看到很多的config config,对吧?啊是因为它需要,呃,把这些配置也分发出去啊,也分发出去,好,那接下来是咱们刚才的一个逻辑啊。
19:16
Set圈里它怎么样呢?首先是不是分为S跟非source,对source同样是调用create圈方法,并且是什么呀?递归调用调用什么?是不是下游节点啊。它是不是索引加一了,是不是下游的节点啊,那从而构建出一个节点链条,那么另外呢,它还会做什么?分析当前节点的出边是不是只有出啊啊出边,那么根据咱们操作链中的。一个可链接就出边是可连接还是不可连接,也就是能不能串对吧?啊分为了可串的跟不可串。那分别对吧,咱们刚才是不是看到了分别递归调用自己啊。
20:02
分别递归掉自己,那么之后呢,呃,就做了一堆什么名字啊ID的封装对吧,放到配置对象里了吧。好,再往下。走另一个逻辑。如果不是链条的子节点。如果不是。链条的直接点则会怎么?把作业顶点跟作业边直接相连呢?是不是直接就相连起来了。把咱们这个圈圈跟后面的这个边,哎,把它连接起来啊,连接起来。如果是子节点,那就把这个加到。配置里面啊,配置里面这个就是它的一个大概的处理逻辑,那么一个节点链条呢,除了。呃。链条节点的头部啊,这个叫这个名字head of圈node会生成对应的作业顶点之外啊,其余的怎么样?
21:05
是不是直接放到那个config里面去了,咱们看的不是很简单的几行吗?哎,以序列号的形式写入到string config里面啊。并且保存起来,保存起来。大家注意这边。有问题吗?整个逻辑。那如果再简化一下,干的什么事啊?干了什么事?是不是按照节点进行遍历,然后呢。把牛节点转成。作业顶点,把牛的边出边这一块转换成。作业出编码,哎,之后把它连接起来,还做了什么呢?是不是一些信息封装到一个叫stream con这个里面啊,就这几个事啊,就这几个事,你看代码看起来会比较绕啊,因为它呃要一步步的处理嘛,啊要一步步的处理。
22:12
啊。呃。就是这嘛。这里这个逻辑啊,你看他判断的是什么。对吧,呃,非开始节点ID,那节点ID是什么地方设的,是不是前面啊。他从哪获取的?是不是链条信息啊,他是外面又做了一些处理吗。
我来说两句