00:00
依赖咱们讲完了,同学们,接下来我们讲一下阶段的划分,那么阶段该如何划分呢?其实在咱们之前画图的时候,这边有一个叫做阶段调度器,咱们叫dag schedule,也称之为叫有向无环图的调度器,它主要用于阶段的划分和任务的切分。那么我们底层是如何实现的呢?咱们回过头来,我们这边会有一个叫做行动算子collect,它会触发整个作业的执行,所以我们点一下,点完以后有一个叫run job,咱们再点,然后再点好,再来点,点击到我们下一步的时候,你会发现这里面就有个叫DA schedule,就是我们刚才画图当中的那个对象,它里面会有一个叫wrong job,咱们点一下,点完以后往这看,它有一个叫submit job,叫提交作业,那好,我们再来往下点,点完之后往下走,往下走,往下走,走到这个位置,你会发现它有一个叫做什么呢?叫job subter的。
01:00
的一个事件,这个事件会怎么办呢?会有个post的点,它会往一个叫的Q里面去,把这个事件放进去,哎,就是这个意思,这个叫even的Q,这个是个队列啊,叫事件队列,它会把刚才的这个来咱们回头叫job submitter的这个事件给它放进去,那放进去以后你该如何把它取出来呢?这里会涉及到一个叫event thread,叫做线程事件线程咱们打开,打开以后这个线程如果启动执行的时候,它会有一个run,这个run呢,就会从咱们的Q里面把它数据取出来,有个叫做take,这个take呢,当你取出来事件以后会怎么办?会叫on receive,咱们点一下,点完以后它是一个我们的抽象的,那么我们回过头就在这儿了,所以拷贝,拷贝以后我们打开,打开以后搜索,搜索以后有个叫on receive,它有个叫do on receive,对不对,所以我们再来点,点完之后大家会发现。
02:00
这个不就叫做jobter的吗?说的简单点,他是往那个事件队列里面发了一条消息,那么当我收到这条消息之后,会做一个模式匹配,来匹配你到底是什么消息,那这里呢,就是一个叫提交作业的消息,然后呢,在这个地方就有一个叫DA schedule的点,叫handle job sumter的,所以我们点点完以后在这个地方,记住啊,在我们的这个地方,它会进行阶段的划分。所以啊,我们的阶段的划分其实就在我们当前的这个位置,那好我们可以简单的看一看,这里面有一个叫stage,咱们拷贝。拷贝以后我拿过来啊,同学们拿过来叫create,叫创建结果result,结果嘛,叫阶段,所以呀,我们再去点,点点完以后大家会发现你什么代码都不用看,你就看到这个位置了,叫做什么呢?叫new result stage,所以啊,你会发现对于我们来讲的话,我们现在其实就有一个阶段,你老说划分阶段,划分阶段到底怎么划分,这不就是一个阶段嘛,所以我们回过头来,同学们往下走,现在呢,其实我们就有一个阶段了啊把这个呢,咱们往下。
03:17
这个往下以后啊,这个咱们就不要了啊,来不要了,不要了以后,我现在呢,把这个咱们放过来,文字呢放到这边啊,咱们叫做result stage,诶就是一个完整的阶段,那你的这个阶段里面你包含什么东西呢?对不对?我们说啊,它要包含的其实就是我们前面的很多的内容,咱们回过头看一下,它会把咱们什么RDD这些东西全包进去,这个RD是什么呀?这个RDD不就是你一步一步传过来的那个最后的RDD吗?大家看我们点开,我们这里叫collect,我们点点完以后不就把你当前的RDD就一步一步传过去了吗?所以说你当前处理的这个RDD其实就是,那么就意味着你这个RDD被包进去了啊,所以我们这个画图的时候,同学们看啊,我们这里来给他拷贝一个吧,嗯,拷贝拷贝一个,那我这边就是一个RDD了啊,就是DD,记住是我们最后的那个RDD,最后的那个RDD,不就是什么什么S的RDD嘛,对不对,所以啊,咱们来把这个拷贝咱们叫S。
04:18
RDD就是它,嗯,好了,但是你光有一个S的RDD行不行不行,为什么呢?大家可以看到它里面是不是包含了很多的内容啊,所以啊,这个包含呢,在这里应该通过依赖关系给它体现出来,所以啊,我觉得咱们这么画可能不合适,咱们这样吧,咱们放过来啊,嗯。呃,这个呢,我们就写上啊,咱们给它用一个我们的蓝色或者绿色好不好呢?用一个绿色吧,啊这个咱们就直接写上,把这个去掉啊,咱们把这个去掉,去掉以后来啊,咱们这边就直接我们写上点东西吧,咱们拷贝,拷贝以后我放到这咱们就叫RDD,好,那么你这个RDD有了之后呢,我们里面比方说我是不是能够画几个分区的感觉呀,嗯,放到这儿来啊。
05:01
然后呢,放过来,放过来以后这是一个分区,诶放过来,然后再往下放,然后再往下放,对不对?诶我们假设有三个分区,那这三个分区呢,再往下,诶放到这边,那好放过来之后我们的箭头记住啊,我们现在的这个分区啊,它可能是一对一的关系,对不对,One two one嘛,所以它有这种依赖关系啊呃,我想想这么画应该也可以啊,它从上游的RDD把数据往下游中传呢,诶没问题,然后呢,再来啊,咱们这个RDD呢也可以,所以拷贝,拷贝以后放到这边通道里,这个呢,拿过来,诶咱们都给它画一画啊,咱们意思意思来,放到这,放到这以后,诶放到这边,然后呢,再来,再往下放,往下放以后这个里面就不能随便放了,为什么呢?因为默认情况下,它里面也是我们的什么三个我们的RDD应该是它啊,不是说错了三个分区,那我在这个地方呢,咱们拿过来,咱们叫做沙Le啊,这个咱们加上一个沙Le,因为它确实有个沙Le,嗯。
06:00
好了,这个咱们应该用黑色吧,这个颜色用白色就不合适了啊,用一个黑色。好,翻过来啊,咱们的一个suffle的RDD,那么既然你有sle的话,大家想想那你该怎么办,你是不是应该怎么办,同学们应该把数据打乱重新组合吧,所以啊,我们的箭头它指向咱们的这个位置啊,来往下走,往下走啊就是这个意思,好,然后呢,这个数据呢,它也往下走,或者说咱别往下走了,往这儿走行不行可以吧,然后呢,我们再来往这儿走也可以吧,然后呢,再来是不是它也可以这样,然后再来啊,把这个数据呢往这边走,然后呢,再来啊把这个数据呢往下走,其实我们随便画一画就可以了,让大家明白这么一个大概的一个思路,嗯,好,然后呢,再来把这个呢,箭头呢往这边放,所以说你会发现呢,咱们数据呢,就已经打乱,重新组合了啊,所以这就是我们的沙的RDD啊,好,那么我们的stage现在呢,就把这个关系给它列出来了啊,那么列出来以后接着往下同学看,这个叫做new,但是里面它还包含了一个什么?
07:06
叫。这个parent在这儿呢?叫get or create parent stage,这句话是什么意思呢?从字面含义上来讲,叫获取或创建上一级的阶段,这就说明啊,咱们的这个ddo stage啊,它可能有上一级的阶段,对不对?那否则为什么叫parent呢?所以我们这边应该有一个上一级的概念,但是这个上一级我怎么知道在哪儿呢?不知道,所以同学们看啊,我这个地方我们就去点一下,点点完以后核心代码就在这个位置,所以咱们拿过来放到这儿啊。这个里面有个方法叫get or create,首先咱们这个地方来咱们说一下它叫做什么呢?写上啊来我们写上叫做创建啊,咱们写上叫做创,诶,呃,创建我们的结果啊阶段,诶,好,那这个呢,写上咱们叫获取,获取啊获我们叫创建我们的上级阶段,那么它里面的逻辑呢,是这样的,同学们看啊,看能不能看懂啊,这个叫get shuffle depends。
08:12
然后把一个RDD传进来了,这个RDD传的是什么呢?传的就是你最后的那个RDD,所以后退,后退以后大家看不就这个DD吗?这个RD不就是传进来的吗?所以说它等同于把这个黄色的RDD干嘛呀,传到了咱们刚才的这个位置,传过来了,传过来以后它的字面含义叫获取依赖,什么意思不知道,我们点进去,点进去以后你会发现它的代码它就在这里,其中它里面的核心逻辑就在这个位置,干嘛呢?判断你的RDD的依赖关系中是不是杀否依赖就是这个意思,那我看是不是啊。大家看咱们这个沙Le RD是不是沙依赖,其实你往上看就行了,咱们的这个沙RDD的依赖关系是不是沙依赖。所以它如果是沙uffle依赖的话,那么就意味着他这边就会有会增加,那么parent就会增加,那么有一个增加一个,那咱们这儿呢,咱们这不就一个嘛,对不对,咱们这就一个沙佛RDD啊,所以它就一定会有一个,那么有一个的话,咱们后退,后退之后,那么这个就会产生一条数据,它产生一条数据以后map,那么map的话是一个转换映射,你有多少条我就转换成多少条,你有一条,那么它就会转换一条,这个地方叫get or create,叫s map stage,所以把这个拿过来啊。
09:37
这个我们写上啊,咱们写上来,咱们写上叫做获取啊来获取获我们叫创建,创建什么呢?我们叫做沙。那咱们叫做shuffle,我们叫map的阶段啊,咱们的阶段,哎,就这意思,说白了什么叫shuffle map呀。咱们之前讲过沙uffle是不是要写磁盘呢?你要写磁盘的话,是不是有一个map和reduce的阶段,对不对,所以啊,沙uffle map阶段说白了就是写磁盘之前的那个阶段,它会分一个,所以说我们这个地方就会创建一个阶段,而这个阶段就是沙Le之前的阶段,所以同学们看,这时候呢,我要把咱们之前的这个图形啊来拷贝,拷贝以后拿过来放到这个位置啊,因为杀否之前不就恰恰是咱们的这个阶段嘛,对不对,所以呀,放过来啊,来把这个自于底层,哎,就这个样子的,所以我们拷贝啊,这个我们写上啊,咱们来,咱们叫沙否。
10:36
Map啊,咱们的stage好了,那这个地方的这个文字啊,咱们这个文字诶。我这个就不要了,咱们这个就不要了,它是一个我们的阶段,好,那这个阶段呢,我们再来往下看一看,我们点,点完以后,你会发现它在创建这个阶段的时候,我们再往下点,它里面会有一个叫做new,它会把当前依赖的那个RDD给你传过来,大家看依赖的那个RDD。
11:00
咱们这个依赖的RDD是不是就是前面那个RDD,说的简单点,这个sale的RDD前面不就是它吗?所以这个RDD就会给它传进来,所以我们来啊,咱们给它画一个紫色,这个紫色是它的那个RDD,这个黄色是这个阶段的那个关联RDD啊。好了,那么关联的RDD之后,那么其实就没有别的了,对不对,哎,就是这样,所以后退后退啊,咱们后退后退之后再来往前啊往前。他把这个依赖关系判断好之后,是不是直接就to list了,就说明啊,我们的阶段呢,基本上到了这一步了,我们的操作就差不多了啊,所以我们这里呢,来搜索一下啊,在我们的这个位置它就创建好了,所以从这个源码的角度来讲,你会发现我们当前的这个地方应该是两个阶段,诶老师那如果这里有个沙口怎么办?其实啊,你再回过去点,点完之后你再看这个代码啊,咱们点一下它这个代码当中,我们再去点,再去往下点。
12:00
往下点到创建这个阶段的时候,其实它上面怎么了,又有一个叫get or create parent叫获取或创建上一级阶段,他会看一看这个RDD,它前面有没有沙uffle,有沙Le的话,会再创建一个阶段,再把这个R再传过去,再往上找,所以啊,它是一个我们什么不断往前找的一个过程,从最后的RDD往前找,只要碰见Le的依赖,它就会创建一个uffle的map stage,就是shuffle的一个,诶,写磁盘的一个阶段,哎,就这么个过程啊,哎,所以说我们这个图这么画应该是对的啊。好了,那这个呢,我们大概就能明白了,哦,原来它的阶段划分是跟这个沙否依赖有关系的,对吗?所以我们回过头来到这个地方啊,咱们来协商一下,嗯。咱们的这个Spark中啊,Spark中我们叫阶段的划分,它等于的是我们的shuffle啊,咱们叫依赖啊沙否。
13:05
赖的数量加一什么意思呢?你有一个杀否依赖,那么再加上一个一,就是最后的这个阶段,那么就是我们当前阶段的数量,比方说我们有一个沙Le依赖,那就有两个阶段,对不对?它是一个,它是一个。这个阶段当执行完毕之后该怎么办?该写磁盘,那么我们的stage是不是应该读磁盘呢?所以他们就分开了啊,就应该是这样的一个过程好不好,同学们,所以啊,把源码呢,咱们大概的看一看,然后呢,把原理咱们说清楚,知道它的阶段如何划分,其实就够了啊。
我来说两句