shuffle全过程理解
理解宽窄依赖
窄依赖(父RDD单个分区的计算不依赖于父RDD其他分区):
父RDD的一个Partition只能对应子RDD的一个Partition。即父RDD的一个分区上的数据可以单独计算。
换句话说,子RDD的某个分区在计算时可以单独计算而不会依赖于父RDD其他Partition上的数据。如Filter,map。
宽依赖(父RDD单个分区的计算依赖于父RDD其他分区):
父RDD的一个Partition无法单独计算,需要依赖于其他所有的Partition(依赖的不确定性)。表现为,shuffle read阶段,多个父RDD的数据,汇聚在同一个partition中计算。
Task分类:
分为ShuffleMapTask和ResultTask。
ShuffleMapTask需要将计算结果shuffle到下一个stage中。
ResultTask输出的则是result。
shuffle write:
总结起来:宽依赖划分了Stage,中间涉及了Shuffle过程,前一个stage的通过ShuffleMapTask进行Shuffle write, 把数据存储在blockManager上面, 并且把数据位置元信息上报到driver的mapOutTrack组件中,下一个stage根据数据位置元信息,进行 shuffle read,拉取上个stage的输出数据,进行数据处理。
https://blog.csdn.net/lidongmeng0213/article/details/106091148
ShuffleWriter类型
在shuffleMapTask的runTask方法中,获取shuffleWriter:
override def getWriter[K, V](
handle: ShuffleHandle,
mapId: Int,
context: TaskContext): ShuffleWriter[K, V] = {
numMapsForShuffle.putIfAbsent(
handle.shuffleId, handle.asInstanceOf[BaseShuffleHandle[_, _, _]].numMaps)
val env = SparkEnv.get
handle match {
case unsafeShuffleHandle: SerializedShuffleHandle[K @unchecked, V @unchecked] =>
new UnsafeShuffleWriter(
env.blockManager