RDD shuffle
shuffle阶段涉及磁盘读写,以图示为例,紫色RDD与ShuffleRDD之间会进行磁盘读写操作,紫色RDD进行磁盘写操作,ShuffleRDD进行磁盘读操作
- 写磁盘
- 读磁盘
核心代码
//读磁盘
override def compute(split: Partition, context: TaskContext): Iterator[(K, C)] = {
val dep = dependencies.head.asInstanceOf[ShuffleDependency[K, V, C]]
val metrics = context.taskMetrics().createTempShuffleReadMetrics()
SparkEnv.get.shuffleManager.getReader(
dep.shuffleHandle, split.index, split.index + 1, context, metrics)
.read()
.asInstanceOf[Iterator[(K, C)]]
}
//写磁盘
val mapId = if (SparkEnv.get.conf.get(config.SHUFFLE_USE_OLD_FETCH_PROTOCOL)) {
partitionId
} else context.taskAttemptId()
dep.shuffleWriterProcessor.write(rdd, dep, mapId, context, partition)
}
写磁盘分析源码步骤
-
在DAGScheduler.scala文件找到submitMissingTasks()方法,找到阶段1ShuffleMapStage
-
进入ShuffleMapTask类中,该类继承父类Task
-
查看父类Task的run()方法,其中runTask()是抽象方法,需要在子类中重写
-
回到ShuffleMapTask,该子类重写了runTask()方法,shuffleWriterProcessor.write()与写文件有关
-
进入write()方法,获取写对象writer,执行写方法write()
-
进入writer.write()方法,该方法为抽象方法
-
进入commitAllPartitions()方法,同样commitAllPartitions()也为抽象方法
-
找到其实现类,进入writeIndexFileAndCommit()方法,该方法与索引文件有关
-
判断索引文件和数据文件是否存在,这部分代码与索引文件和数据文件有关
读磁盘分析源码步骤
-
在DAGScheduler.scala文件找到submitMissingTasks()方法,找到阶段2 ResultStage,进入ResultTask类中
-
找到重写的runTask方法
-
进入getOrCompute()
-
进入computeOrReadCheckpoint()
-
进入compute()
-
compute()为抽象方法, 每个RDD都要实现该方法,因为此时的RDD为shuffledRDD(如开头图片所示),进入ShuffledRDD
-
与读磁盘相关