版权声明:本文为原创文章,未经允许不得转载。
复习内容:
Spark中Stage的提交 http://www.cnblogs.com/yourarebest/p/5356769.html

Spark中Task的提交

1.在复习内容部分我们介绍了在方法onStageSubmitted中,Stage的提交,那么在该方法中还有Task的提交,如下所示:

override def onStageSubmitted(stageSubmitted: SparkListenerStageSubmitted): Unit = synchronized {
//(1)Stage的提交,详见文章-Spark中Task的提交
//(2)Task的提交
//broadcasted task的二进制,用来分发tasks给executors。
//注意:我们broadcast RDD的拷贝并且对于每一个task我们将要反序列化,这意味着每个task得到一个不同的RDD 拷贝
var taskBinary: Broadcast[Array[Byte]] = null
try {
// For ShuffleMapTask, serialize and broadcast (rdd, shuffleDep).
// For ResultTask, serialize and broadcast (rdd, func).
val taskBinaryBytes: Array[Byte] = stage match {
case stage: ShuffleMapStage =>
closureSerializer.serialize((stage.rdd, stage.shuffleDep): AnyRef).array()
case stage: ResultStage =>
closureSerializer.serialize((stage.rdd, stage.func): AnyRef).array()
}
//将序列化后的task广播出去
taskBinary = sc.broadcast(taskBinaryBytes)
} catch {
case e: NotSerializableException =>
abortStage(stage, "Task not serializable: " + e.toString, Some(e))
runningStages -= stage
return
case NonFatal(e) =>
abortStage(stage, s"Task serialization failed: $e\n${e.getStackTraceString}", Some(e))
runningStages -= stage
return
}
//根据stage生成tasks
val tasks: Seq[Task[_]] = try {
stage match {
//对于ShuffleMapStages生成ShuffleMapTask
case stage: ShuffleMapStage =>
partitionsToCompute.map { id =>
val locs = taskIdToLocations(id)
val part = stage.rdd.partitions(id)
//可见一个partition,一个task,一个位置信息
new ShuffleMapTask(stage.id, stage.latestInfo.attemptId,
taskBinary, part, locs, stage.internalAccumulators)
}
//对于ResultStage生成ResultTask
case stage: ResultStage =>
val job = stage.resultOfJob.get
partitionsToCompute.map { id =>
val p: Int = stage.partitions(id)
val part = stage.rdd.partitions(p)
val locs = taskIdToLocations(id)
new ResultTask(stage.id, stage.latestInfo.attemptId,
taskBinary, part, locs, id, stage.internalAccumulators)
}
}
} catch {
case NonFatal(e) =>
abortStage(stage, s"Task creation failed: $e\n${e.getStackTraceString}", Some(e))
runningStages -= stage
return
}
//如果tasks的num大于0
if (tasks.size > 0) {
logInfo("Submitting " + tasks.size + " missing tasks from " + stage + " (" + stage.rdd + ")")
stage.pendingPartitions ++= tasks.map(_.partitionId)
logDebug("New pending partitions: " + stage.pendingPartitions)
//调用taskScheduler提交TaskSet,详见2
taskScheduler.submitTasks(new TaskSet(
tasks.toArray, stage.id, stage.latestInfo.attemptId, stage.firstJobId, properties))
stage.latestInfo.submissionTime = Some(clock.getTimeMillis())
} else {
//因为我们之前就已经发送了事件SparkListenerStageSubmitted,所以我们标记Stage为completed防止没有任务提交
markStageAsFinished(stage, None)
//将debugString记录到日志中
val debugString = stage match {
case stage: ShuffleMapStage =>
s"Stage ${stage} is actually done; " +
s"(available: ${stage.isAvailable}," +
s"available outputs: ${stage.numAvailableOutputs}," +
s"partitions: ${stage.numPartitions})"
case stage : ResultStage =>
s"Stage ${stage} is actually done; (partitions: ${stage.numPartitions})"
}
logDebug(debugString)
}
}

2.Task的提交会调用taskScheduler的submitTasks方法进行,TaskScheduler是trait,它的唯一的具体实现是TaskSchedulerImpl,submitTasks方法如下所示:

override def submitTasks(taskSet: TaskSet) {
val tasks = taskSet.tasks
logInfo("Adding task set " + taskSet.id + " with " + tasks.length + " tasks")
this.synchronized {
//为一个taskSet创建一个TaskSetManager
val manager = createTaskSetManager(taskSet, maxTaskFailures)
val stage = taskSet.stageId
val stageTaskSets =
taskSetsByStageIdAndAttempt.getOrElseUpdate(stage, new HashMap[Int, TaskSetManager])
stageTaskSets(taskSet.stageAttemptId) = manager
val conflictingTaskSet = stageTaskSets.exists { case (, ts) =>
ts.taskSet != taskSet && !ts.isZombie
}
if (conflictingTaskSet) {
throw new IllegalStateException(s"more than one active taskSet for stage $stage:" +
s" ${stageTaskSets.toSeq.map{
._2.taskSet.id}.mkString(",")}")
}
//将taskSetManager和taskSet添加到两种可调度的tree中,FIFO or FAIR
schedulableBuilder.addTaskSetManager(manager, manager.taskSet.properties)
if (!isLocal && !hasReceivedTask) {
//一个定时器
starvationTimer.scheduleAtFixedRate(new TimerTask() {
override def run() {
if (!hasLaunchedTask) {
logWarning("Initial job has not accepted any resources; " +
"check your cluster UI to ensure that workers are registered " +
"and have sufficient resources")
} else {
this.cancel()
}
}
}, STARVATION_TIMEOUT_MS, STARVATION_TIMEOUT_MS)
}
hasReceivedTask = true
}
//不同(集群)模式进行资源的分配
backend.reviveOffers()
}

这样我们就完成了Task的提交,那么不同模式对于Task的资源又是如何分配的呢,我们后面介绍。

【原】 Spark中Task的提交源码解读的更多相关文章

  1. 【原】Spark中Job的提交源码解读

    版权声明:本文为原创文章,未经允许不得转载. Spark程序程序job的运行是通过actions算子触发的,每一个action算子其实是一个runJob方法的运行,详见文章 SparkContex源码 ...

  2. 【原】Spark中Stage的提交源码解读

    版权声明:本文为原创文章,未经允许不得转载. 复习内容: Spark中Job如何划分为Stage http://www.cnblogs.com/yourarebest/p/5342424.html 1 ...

  3. HttpServlet中service方法的源码解读

    前言     最近在看<Head First Servlet & JSP>这本书, 对servlet有了更加深入的理解.今天就来写一篇博客,谈一谈Servlet中一个重要的方法-- ...

  4. sklearn中LinearRegression使用及源码解读

    sklearn中的LinearRegression 函数原型:class sklearn.linear_model.LinearRegression(fit_intercept=True,normal ...

  5. 【原】Spark不同运行模式下资源分配源码解读

    版权声明:本文为原创文章,未经允许不得转载. 复习内容: Spark中Task的提交源码解读 http://www.cnblogs.com/yourarebest/p/5423906.html Sch ...

  6. 15、Spark Streaming源码解读之No Receivers彻底思考

    在前几期文章里讲了带Receiver的Spark Streaming 应用的相关源码解读,但是现在开发Spark Streaming的应用越来越多的采用No Receivers(Direct Appr ...

  7. Spark技术内幕:Stage划分及提交源码分析

    http://blog.csdn.net/anzhsoft/article/details/39859463 当触发一个RDD的action后,以count为例,调用关系如下: org.apache. ...

  8. Spark学习之路 (十六)SparkCore的源码解读(二)spark-submit提交脚本

    一.概述 上一篇主要是介绍了spark启动的一些脚本,这篇主要分析一下Spark源码中提交任务脚本的处理逻辑,从spark-submit一步步深入进去看看任务提交的整体流程,首先看一下整体的流程概要图 ...

  9. Apache Spark源码走读之23 -- Spark MLLib中拟牛顿法L-BFGS的源码实现

    欢迎转载,转载请注明出处,徽沪一郎. 概要 本文就拟牛顿法L-BFGS的由来做一个简要的回顾,然后就其在spark mllib中的实现进行源码走读. 拟牛顿法 数学原理 代码实现 L-BFGS算法中使 ...

随机推荐

  1. PHP学习心得(四)——基本语法

    从 HTML 中分离 当 PHP 解析一个文件时,会寻找开始和结束标记,标记告诉 PHP 开始和停止解释其中的代码.此种方式的解析可以使 PHP 嵌入到各种不同的文档中,凡是在一对开始和结束标记之外的 ...

  2. python 数据类型(列表)学习笔记

    列表 创建列表: name_list = ['alex', 'seven', 'eric'] 或 name_list = list(['alex', 'seven', 'eric']) 其实今天学习的 ...

  3. hdu 4542 小明系列故事——未知剩余系

    小明系列故事——未知剩余系 题意:操作0表示某数有n个约数,操作1为某数有n个非约数:n <= 47777,若是存在小于2^62的数符合,则输出该数,否则若是不存在输出Illegal,若是大于2 ...

  4. JQ+AJAX实现多级联动

    利用JQ与AJAX实现三级联动实现的效果: 当前两级改变时,后边一级或两级都会改变: 使用的数据库: html代码: <!doctype html> <html lang=" ...

  5. VS2010制作网站自定义安装程序 转

    最近在把一个网站打包成安装程序,这方面的文章网上有很多,也看了不少,但因为开发环境的不同,遇到了一些问题,便写下这篇文章记下整个流程(有很多资源都来自互联网,由于条目颇多,所以无法说明其来处,敬请谅解 ...

  6. treeview 点击时选中节点

    private void tv_WebList_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { Point clickPo ...

  7. POJ 2289 Jamie's Contact Groups & POJ3189 Steady Cow Assignment

    这两道题目都是多重二分匹配+枚举的做法,或者可以用网络流,实际上二分匹配也就实质是网络流,通过枚举区间,然后建立相应的图,判断该区间是否符合要求,并进一步缩小范围,直到求出解.不同之处在对是否满足条件 ...

  8. SPRING IN ACTION 第4版笔记-第四章ASPECT-ORIENTED SPRING-012-AOP总结

    1.AOP是面向对象编程的有力补充,它可以让你把分散在应用中的公共辅助功能抽取成模块,以灵活配置,减少了重复代码,让类更关注于自身的功能

  9. 告别山寨数据线:USB Type-C加密认证出炉

    从去年苹果发布的MacBook首次采用USB Type-C接口开始,这一标准逐渐成为主流,许多旗舰手机慢慢地采用了这种接口.今日,非盈利机构USB开发者论坛(USB-IF)宣布了USB Type-C认 ...

  10. [Quick-x]制作新手引导高亮区域方法之二:裁剪模式

    demo下载:https://github.com/chenquanjun/Quick-x-HighlightArea 2.裁剪模式 (1)创建裁剪对象 , , ) --非高亮区域颜色 local b ...