后面讲了Task的创立、提交,以及对Task进行资源调度与调配,对于Task的实现细节一笔带过,所以这篇开始解说Task的执行过程。Task又分为ShuffleMapTask和ResultTask,咱们离开来讲。
ShuffleMapTask
ShuffleMapTask进行写入的时候,有三种形式,别离是UnsafeShuffleWriter、BypassMergeSortShuffleWriter、SortShuffleWriter。而最终应用哪个ShuffleWriter是取决于RDD依赖的ShuffleHandle。
如果不须要map端进行合并且分区数小于等于200,则ShuffleHandle为BypassMergeSortShuffleHandle,最终的ShuffleWriter是BypassMergeSortShuffleWriter。
如果不须要map端进行合并且分区数<16777216、Serializer反对relocation则ShuffleHandle为SerializedShuffleHandle,最终的ShuffleWriter是UnsafeShuffleWriter。
其余状况下,ShuffleHandle为BaseShuffleHandle,最终的ShuffleWriter是SortShuffleWriter。
上面就先介绍BypassMergeSortShuffleWriter的写入过程,其余两个留前面讲。
BypassMergeSortShuffleWriter
咱们假如有2个分区,这样最终就有2个Task,假如每个Task发给一个Executor,上面看看Executor是怎么解决每个Task中RDD计算的数据。
首先Executor会依据分区的数量,创立等同数量的DiskBlockObjectWriter。因为咱们的分区数是2,所以DiskBlockObjectWriter是个数也是2,每一个DiskBlockObjectWriter解决一个分区的数据,最初把map工作的输入写入磁盘。每个DiskBlockObjectWriter都维持着BlockId以及他的文件File。
DiskBlockObjectWriter筹备好后,开始迭代RDD计算的后果records,假如第一条是(a,1),应用分区计算器算出a这个key的分区,比方右边的分区0,而后让右边的DiskBlockObjectWriter把(a,1)写入到Shuffle文件的输入流中。同理,(b,1),(c,1),(d,1)也假如都在右边,(e,1),(f,1),(g,1),(h,1)依据key的分区计算,都在左边。
records后果都解决完后,DiskBlockObjectWriter就会把输入流中的数据写入到磁盘,文件的信息、索引的地位,都交给FileSegment来解决。
此时曾经生成了两个长期的Shuffle文件,为了缩小网络的IO,这些临时文件须要进行合并。所以会把这两个长期的Shuffle文件内容,写入到Shuffle数据文件,并记录每个文件的长度(比方4,4)。
写入到Shuffle数据文件后,临时文件就没有用了,就把他们都删除。
此时还要一个索引文件,因为咱们把两个文件的内容合并了,须要晓得原先每个文件里有哪些货色,下面咱们不是保留了文件的长度(4,4),所以依据这个失去了索引的值(0,4,8)。这样咱们从文件里拿到对应的数据,就能够通过索引了。
ResultTask
如果一个RDD的数据,最终发到3个Executor,每个Executor都只解决一个Task,那最初会有3个dataFile文件。
最初执行ResultTask的时候,就会从这些dataFile文件拿出数据,调用函数进行最终的解决,失去最初的后果。