大数据Shuffle原理与实践|青训营笔记

115 阅读2分钟

这是我参与「第四届青训营 」笔记创作活动的第6天

在学习Spark的Shuffle流程之前,先要学习几个概念


  • Shuffle Dependency:创建会产生Shuffle的RDD时,同时会创建一个ShuffleDependency来描述Shuffle相关的信息
  • Aggregator:Shuffle时的性能优化器,提前在map端聚合,减少shuffle数据量

Spark Shuffle发展历史


image.png 现在我们跟着历史,一步一步学习Spark是怎么演进的。

我们先假设,有M个task,每个task有R个partitition,CPU核数为C个

Hash Based Shuffle Write V1.0


每一个Partitition都会把数据写到一个独立文件里,会生成M*R个文件

  • 这样缺点很明显产生的中间数据文件太多了

image.png

Hash Based Shuffle Write V2.0


image.png 每个Partition把数据写入到一个文件片段,由于CPU核数有限,有M个task,但是同一时间并行跑的task只有C个,只生成C*R个文件

  • 缺点:虽然CR < MR,但是依然会产生很多中间数据文件

Sort Based Shuffle Write


image.png 每个Map Task生成一个包含所有Partitition数据的文件。原来的HashShuffle每个task要给每个分区生一个文件,现在经过排序以后,一个task只需要生成一个文件

  • 这样一共只需要生成M个文件,中间数据文件数量大幅减少

Shuffle Read


不管是HashShuffle还是SortShuffle,Reduce端读取的方法都差不多

每个reduce task分别拉取自己的片段

image.png 这个拉取数据的过程中,有一个External Shuffle Service (ESS) 服务,这个服务在每个节点上。

Writer端呢会把数据存储的文件位置告诉这个ESS服务,然后Reducer端要fetch数据的时候会提交请求给ESS服务,这样就把Writer和Reader两个操作给解耦开了。

image.png

Shuffle触发流程


上节课我们学过了RDD从创建到执行中间的流程,这里讲一下主要针对shuffle的流程

image.png 当RDD触发action算子后,会调用DAGScheduler的submitJob,这个过程会分析RDD的依赖关系,根据这个依赖关系创建对应的Shuffle对象,然后向ShuffleManager注册自己,之后生成stage,然后发送task去执行

那么shuffle对象是怎么创建注册的?


image.png 其实是根据RDD的信息去创建最合适的ShuffleHandle,然后使用ShuffleHandle去创建对应ShuffleWriter,我们刚刚讲过有很多种ShuffleWrite的方法,这里就可以根据实际的适用场景去选择最合适的ShuffleWrite方法。

Shuffle优化


接下来介绍几个可以优化Shuffle的方法

  • 避免使用Shuffle,用broadcast+map代替join

image.png

  • 使用map-side combine的算子

  • shuffle参数优化

image.png

  • shuffle数据倾斜优化:提高并行度、AQE

至此,这节课的内容基本学习完毕,还有个Push Shuffle是业界最新的shuffle算法,感兴趣可以继续研究