十三、shuffle原理与源码剖析

1. 默认shuffle原理图

上图中,有两个节点,第一个节点上运行了4个ShuffleMapTask,第二个节点上运行了4个ResultTask。ResultTask要去拉取ShuffleMapTask的输出数据,来完成比如reduceBykey等类型的shuffle操作。

每个ShuffleMapTask都会为每个ResultTask创建一份bucket缓存,以及对应的ShuffleBlockFile磁盘文件。ShuffleMapTask的输出,会以MapStatus的形式发送到DAGScheduler的MapOutputTrackerMaster中;MapStatus包含了每个ResultTask要拉取的数据大小。

如果有100个map task,100个result task,那么本地磁盘要产生100 * 100 = 10000个文件,磁盘io过多,影响性能。

每个ResultTask会用BlockStoreShuffleFetcher去MapOutputTrackerMaster获取自己要拉取的文件信息,然后底层通过BlockManager将数据拉取过来。

2. 优化shuffle原理图

优化了的shuffle,引入了consolidation机制,提出了shuffleFileGroup的概念。

如上图所示,ShuffleMapTask所在节点,有4个ShuffleMapTask和2个cpu core,能同时运行2个ShuffleMapTask。第一批运行的为编号1、3的ShuffleMapTask,它们会分别创建一个shuffleFileGroup。编号2、4的ShuffleMapTask会在第二批次运行,2号ShuffleMapTask共用1号ShuffleMapTask的文件,4号ShuffleMapTask共用3号ShuffleMapTask的文件。

开启了consolidation机制之后的shuffle write操作,每个节点上的磁盘文件数量,变成了 cpu core数量 * ResultTask数量,大大减少了磁盘io的次数。

扫描二维码关注公众号,回复: 5299327 查看本文章

每个磁盘文件中都存储了多个ShuffleMapTask的数据,每个ShuffleMapTask的数据,叫做一个segment。文件中通过索引信息来区分不同的ShuffleMapTask数据。

要开启consolidation机制,只需要在SparkConf中进行配置即可。

以上是spark2.0之前的shuffle原理,作为补充,还可以参考spark调优/四、Spark性能优化:shuffle调优 的内容:

https://blog.csdn.net/tianlan996/article/details/85269533

3. spark2.0之后,map任务在输出时,会进行分区计算并生成数据文件和索引文件等步骤,可能还伴随有缓存、排序、聚合、溢出、合并等操作。reduce任务将map任务输出的Block划分为本地和远端的Block,对于远端的Block,需要使用ShuffleClient从远端节点下载,而对于本地的Block,只需要从本地的存储体系中读取即可。reduce任务读取到map任务输出的数据之后,可能进行缓存、排序、聚合、溢出、合并等操作,最终输出结果。

源码剖析 待续。。。

猜你喜欢

转载自blog.csdn.net/tianlan996/article/details/87479306