shuffleBlockManager继承于Logging,参数为blockManager和shuffleManager。shuffle文件有三个特性:shuffleId,整个shuffle stage所具有的唯一Id;bucketId,输出的partition的Id;fileId,标志着这一组文件属于同一个shuffle,每个task在同一时间只有一个fileId,执行完成后fileId归还资源池。shuffle的状态由shuffleState类来描述,包含其相关的所有状态信息,包括:分配给该shuffle的fileGroup(已使用的和全部的两种);完成的mapTask的Id,这些mapTask是指shuffle所在executor上为它所需要的所有mapTask。

1、addCompleteMap():添加已经完成的、符合条件的mapTask至shuffleState。这个方法应该在基于sort的shuffle中使用,因为只有基于sort的shuffle才会在map完成后在单个文件内进行排序(并不是整个文件进行排序!)。

2、forMapTask():给定mapTask后,生成shuffleWriteGroup。map的结果写入文件,需要创建一个writers对BlockManager提供的block进行写操作。同时,在创建的shuffleWriteGroup中定义新的操作函数,releaseWriters,释放writers操作;getUnusedFileGroup,根据shuffleState获取未使用的FileGroup;newFileGroup,新建FileGroup,需要向BlockManager拉取文件信息,组成洗呢FileGroup。

3、getBlockLocation():给定shuffleBlockId,查找其物理文件所在的地址。这个方法只有在shuffle file允许consolidation时才能被使用,因为consolidation涉及到shuffle的相关文件的consolidation,必须根据shuffleBlockId查找物理文件。

4、removeShuffle()和removeShuffleBlocks():前者移除Shuffle相关的block、file和中间数据,后者不移除中间数据。

定义了一个ShuffleBlockManager的对象,该对象需要存储FileGroup所在的第一个block的Id,偏移位置等,能够快速获取Shuffle所需文件。

 

从MapOutputTracker到shuffleBlockManager阶段需要经过以下方面:

1、写入Block,相关文件为BlockObjectWriter.scala,负责将数据写入Block;

2、shuffle匹配Block中的数据,相关文件为BlockStoreShuffleFetcher.scala。

因此完整的路径为:

MapOutPutTracker:将Map的输出做负载均衡,因为file之间不平衡将导致文件传输的不平衡,与原来的shuffle读取file中的segment有区别。

BlockObjectWriter:将Map的输出写入block,原先的数据写入是严格区分segment然后压缩,新的方法是不用区分segment,方便解压缩数据后整个文件能够直接使用。

BlockStoreShuffleFetcher:按照shuffleId将数据块拼接到一个文件中,供worker拉取。

ShuffleBlockManager:拉取到文件后,获取相应的分块,然后进行Shuffle操作。