今天看了一下关于 job 中 stage 的关系时,发现了ResultStage 和 ShuffleMapStage 两个类。这里先介绍一下job、stage、task的关系。
首先 job 的个数取决于 active 行动算子的个数。当流程执行一个 active 行动算子,spark就会生成一个 job 。
而一个 job 分为多个 stage 阶段,stage 的个数取决于宽依赖的个数,对于宽依赖大家可以自行百度,我这里说一个简单的概念。即分区内的数据如果改变(打乱重新组合)了就算是宽依赖。宽依赖一定伴随着shuffle。
其次一个 stage 阶段包含多个 task 任务,task 任务的个数取决于当前stage阶段的最后一个rdd 的分区数。不同的rdd的分区数计算规则也不同。要根据具体的生产环境确定。
好啦,这三者的关系介绍完了,进入今天的主题。
我在追踪源码的过程中,发现job提交的时候new了一个Activejob对象
点进去以后发现了这个类的numPartions方法,它是运用模式匹配,匹配 ResultStage 和 ShuffleMapStage 两个类。其目的是将 stage 阶段最后的分区数保存起来,以便将来求出task的数量。
此时我们分别打开类ResultStage 和类 ShuffleMapStage
根据我三级英语水平一翻译,得知,ShuffleMapstage主要记录的是为shuffle阶段产生数据的前的一个状态。那它为什么要记录这个呢?
因为一旦进行shuffle阶段之后,必然会产生宽依赖。产生宽依赖就意味着这个stage阶段的结束。也就是说ShuffleMapStage类就是这个stage阶段结束的最后一个rdd时的状态。
那为什么要保留这个状态呢。
因为上面说过task的数量取决于stage阶段最后一个rdd的分区数。所以当spark想要确定task的数量的时候他就会通过ShuffleMapStage来获取。
其实这样说不是很严谨。因为stage阶段的结束不止只有宽依赖这一种情况。还有一种情况就是整个程序运行行动算子的时候。因为运行完行动算子,此次job就会结束,最后一个stage阶段的task数量只能取决于运行此次行动算子之前的rdd的分区数。此时也就有了类ResultStage
ResultStage类中保存着行动算子结束前最后一次rdd的分区数。也由此确定task的数量。
希望各位大佬多提意见。小弟一定虚心接受。
此致