Spark源码阅读笔记之任务调度(一)
主要讨论spark任务调度的对象。
Spark任务调度的对象从大到小可以分为:应用(Application)、作业(Job)、阶段(Stage)、任务(Task)。用户写的spark程序就是一个应用,应用可以提交到集群(yarn、messos或spark原生集群)运行,一个spark应用运行期间可以执行多个spark作业,作业被分割为多个阶段,每个阶段是完成相同功能的任务的集合。
应用(Application)
应用是用户提交的spark程序,例如wordcount程序
object WordCount {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName("WordCount")
val sc= new SparkContext(conf)
val rdd=sc.textFile("data.txt") //your data path
val wordWount=rdd.flatMap(_.split("\\s+")).map((_, 1)).reduceByKey(_ + _)).collect
sc.stop()
}
}
作业(Job)
一个spark应用可以提交多个spark作业,RDD的Action算子会触发作业的提交,如上例中的collect。Transformation算子只是进行RDD之间的转换,不触发作业的提交,如上例中的map和flatMap都将原RDD转换为MapPartitionsRDD,reduceByKey一般会将原RDD转换为ShuffledRDD(在特殊情况下会转换为MapPartitionsRDD,从而避免洗牌)。关于RDD的详细介绍请参考Spark源码阅读笔记(RDD)。
RDD的collect算子:
/**
* Return an array that contains all of the elements in this RDD.
*/
def collect(): Array[T] = {
val results = sc.runJob(this, (iter: Iterator[T]) => iter.toArray)
Array.concat(results: _*)
}
RDD的Action算子触发作业提交,会调用SparkContext中提交作业(runJob)的方法,SparkContext所有作业提交的方法最终都调用DAGScheduler中的submitJob或runApproximateJob方法。submitJob方法以非阻塞的形式提交作业,并返回JobWaiter,用户可以调用JobWaiter中的awaitResult方法等待作业完成,并取得结果,或者调用cancel方法来取消作业的运行。runApproximateJob方法以阻塞的形式提交作业,并设定等待时间,当等待时间到达时用户会得到近似或完整(作业运行完)的结果。
submitJob方法:
/**
* Submit a job to the job scheduler and get a JobWaiter object back. The JobWaiter object
* can be used to block until the the job finishes executing or can be used to cancel the job.
*/
def submitJob[T, U](
rdd: RDD[T],
func: (TaskContext, Iterator[T]) => U,
partitions: Seq[Int],
callSite: CallSite,
allowLocal: Boolean,
resultHandler: (Int, U) => Unit,
properties: Properties): JobWaiter[U] = {
// Check to make sure we are not launching a task on a partition that does not exist.
val