1.概述

本文是基于spark on yarn的执行分析spark整体执行流程是怎么样的。

我们知道spark程序提交的任务,会拆分成ShuffleMapStage,ResultStage。首先会执行ShuffleMapStage,再执行ResultStage,那么问题来了:

1)当Executor执行SchuffleMapstage任务的时候 driver端在做什么?

2)当一个ShuffleMapStage执行完是如何启动下一个ResultStage的计算? 

3)  当一个stage中分区数据量大于executor solt的数量,一个任务完成,如何执行下一个任务?例如:ShuffleMapStage有4分区,此时只有2个executor,只能同时执行两个任务,另外两个再等待。那么这两个等待的任务是何时执行的呢?

 

2.执行spark任务代码的代码:

看一下需要运行的代码,很简单wordcount。

object WordCount {

  def main(args: Array[String]) {

    System.setProperty("hadoop.home.dir","C:\\hadoop")

    val sparkConf = new SparkConf().setMaster("local").setAppName("wordCount")
    sparkConf.set("spark.network.timeout","600")
    sparkConf.set("spark.executor.heartbeatInterval","500")
    val sc =new SparkContext(sparkConf)

    val rdd:RDD[String] = sc.textFile("data/wc.txt",2) //MapPartitionsRDD[1] <-HadoopRDD[0]

    val rdd2 = rdd.flatMap{line => line.split(" ")}//MapPartitionsRDD[2]

    val rdd3 = rdd2.map{word => word ->1} //MapPartitionsRDD[3]

    val rdd4 = rdd3.reduceByKey(_ + _) //ShuffledRDD

    println(rdd4.toDebugString)

    //触发job执行
    rdd4.foreach(println)

    Thread.sleep(100000000)

3.执行 时序图:

spark yarn 运行流程 spark on yarn执行流程_spark yarn 运行流程

时序图解释:

  (1) 从执行rdd.foreach(println)开始分析,

(2)12步到27步:首先执行shuffleMapTask,执行完成executor给driver发送StatusUpdate(taskId, state, serializedData)消息

(3)28步driver接收到消息,开始处理任务状态更新(源码在下图):

 首先,如果stage的所有的partition任务完成,调用submitWaitingChildStages()方法则执行childStage. 执行的步骤是30步到43步 (不包含33-35步)。

另外,如果stage的没有partition任务完成,则继续执行task 。执行步骤为:33步到35步。

spark yarn 运行流程 spark on yarn执行流程_spark yarn 运行流程_02

 

 

4.回答开始的问题:

 

1)当Executor执行SchuffleMapstage任务的时候 driver端在做什么?

  等待executor的StatusUpdate消息,根据消息执行相关操作。

2)当一个ShuffleMapStage执行完是如何启动下一个ResultStage的计算? 

 executor执行任务完成之后,回调给driver StatusUpdate(taskId, state, serializedData)消息,首先更新stage的状态,如果stage的所有的partition任务完成,调用submitWaitingChildStages()方法则执行childStage。

3)  当一个stage中分区数据量大于executor solt的数量,一个任务完成,如何执行下一个任务?例如:ShuffleMapStage有4分区,此时只有2个executor,只能同时执行两个任务,另外两个再等待。那么这两个等待的任务是何时执行的呢?

executor执行执行任务完成之后,回调给driver StatusUpdate(taskId, state, serializedData)消息,此时会把driver端维护的executor信息中的cup个数和内存给加回去(之前执行任务剪掉部分,再加回去)。 如果stage的没有partition任务完成,则继续执行task.