Spark Core(三)Executor上是如何launch task(转载)
1. 启动任务
case LaunchTask(data) =>
if (executor == null) {
exitExecutor(, "Received LaunchTask command but executor was null")
} else {
val taskDesc = ser.deserialize[TaskDescription](data.value)
logInfo("Got assigned task " + taskDesc.taskId)
executor.launchTask(this, taskId = taskDesc.taskId, attemptNumber = taskDesc.attemptNumber,
taskDesc.name, taskDesc.serializedTask)
}
def launchTask(
context: ExecutorBackend,
taskId: Long,
attemptNumber: Int,
taskName: String,
serializedTask: ByteBuffer): Unit = {
val tr = new TaskRunner(context, taskId = taskId, attemptNumber = attemptNumber, taskName,
serializedTask)
runningTasks.put(taskId, tr)
threadPool.execute(tr)
}
方法中通过线程池中启动了线程运行TaskRunner的任务
private val threadPool = ThreadUtils.newDaemonCachedThreadPool("Executor task launch worker")
2. 任务的运行
2.1 加载Jars文件
- timestamp:这是用于判断文件的时间戳,在相同文件名的情况下只有新的才需要重新fetch
- jarName: 这里的JarName是网络文件名:spark://192.168.121.101:37684/jars/spark-examples_2.11-2.1.0.jar
for ((name, timestamp) <- newJars) {
val localName = name.split("/").last
val currentTimeStamp = currentJars.get(name)
.orElse(currentJars.get(localName))
.getOrElse(-1L)
if (currentTimeStamp < timestamp) {
logInfo("Fetching " + name + " with timestamp " + timestamp)
// Fetch file with useCache mode, close cache for local mode.
Utils.fetchFile(name, new File(SparkFiles.getRootDirectory()), conf,
env.securityManager, hadoopConf, timestamp, useCache = !isLocal)
currentJars(name) = timestamp
// Add it to our class loader
val url = new File(SparkFiles.getRootDirectory(), localName).toURI.toURL
if (!urlClassLoader.getURLs().contains(url)) {
logInfo("Adding " + url + " to class loader")
urlClassLoader.addURL(url)
}
}
在Utils.fetchFile里还做了一层cache,受参数控制
spark.files.useFetchCache
/tmp/spark-e9555893--4a56-a692-54a984c3addb/executor-4b9581ca-fe9f-4e96-9db0-192146158a44/spark-bf41fdbd-a84e-473a-aa60-76480745b50b
缓存文件的命名规则:
/tmp/spark-e9555893--4a56-a692-54a984c3addb/executor-4b9581ca-fe9f-4e96-9db0-192146158a44/spark-bf41fdbd-a84e-473a-aa60-76480745b50b
缓存文件的命名规则:
s"${url.hashCode}${timestamp}_cache"
- 检查本地是否有相同的缓存文件
- 如果没有,先Fetch文件从Driver中获取,通过URL:(
spark://192.168.121.101:37684/jars/spark-examples_2.11-2.1.0.jar
)复制到本地的缓存文件
- 复制本地缓存文件到工作目录 /work/app-ID/executorid/
- 设置工作目录文件具有可执行权限
2.2 运行task
val res = task.run(
taskAttemptId = taskId,
attemptNumber = attemptNumber,
metricsSystem = env.metricsSystem)
2.3 反序列化RDD,Dependency
val (rdd, dep) = ser.deserialize[(RDD[_], ShuffleDependency[_, _, _])](
ByteBuffer.wrap(taskBinary.value), Thread.currentThread.getContextClassLoader)
_executorDeserializeTime = System.currentTimeMillis() - deserializeStartTime
_executorDeserializeCpuTime = if (threadMXBean.isCurrentThreadCpuTimeSupported) {
threadMXBean.getCurrentThreadCpuTime - deserializeStartCpuTime
} else 0L
也就是基于taskBinary.value来进行反序列化获得,在来看taskBinary成员
taskBinary: Broadcast[Array[Byte]],
/** Get the broadcasted value. */
def value: T = {
assertValid()
getValue()
}
在前面博客章节中关于Spark Storage管理中提到在集群下使用的是TorrentBroadcast
@transient private lazy val _value: T = readBroadcastBlock()
在前面的storage 系列(一)里面已经谈到过当本地的broadcastId不存在的时候,会尝试去远端(也就是Driver)获取内容,这里的BroadcastId格式是
broadcast_executorID
博客中也提到了同一个Executor拥有一个Block,一个大Block也存在多个Piece的小Block, 也就是格式
broadcast_executorID_pieceid
val blocks = readBlocks().flatMap(_.getChunks())
logInfo("Reading broadcast variable " + id + " took" + Utils.getUsedTimeMs(startTimeMs)) val obj = TorrentBroadcast.unBlockifyObject[T](
blocks, SparkEnv.get.serializer, compressionCodec)
// Store the merged copy in BlockManager so other tasks on this executor don't
// need to re-fetch it.
val storageLevel = StorageLevel.MEMORY_AND_DISK
if (!blockManager.putSingle(broadcastId, obj, storageLevel, tellMaster = false)) {
throw new SparkException(s"Failed to store $broadcastId in BlockManager")
}
2.4 序列化RDD,Dependency
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 =>
JavaUtils.bufferToArray(
closureSerializer.serialize((stage.rdd, stage.shuffleDep): AnyRef))
case stage: ResultStage =>
JavaUtils.bufferToArray(closureSerializer.serialize((stage.rdd, stage.func): AnyRef))
} taskBinary = sc.broadcast(taskBinaryBytes)
} catch {
// In the case of a failure during serialization, abort the stage.
case e: NotSerializableException =>
abortStage(stage, "Task not serializable: " + e.toString, Some(e))
runningStages -= stage // Abort execution
return
case NonFatal(e) =>
abortStage(stage, s"Task serialization failed: $e\n${Utils.exceptionString(e)}", Some(e))
runningStages -= stage
return
}
3 总结:
- TaskDescription 只是包含了任务需要的文件列表,jar文件,配置相关属性,并没有这些具体的文件
- 具体的文件下载路径是Driver直接在TaskDescription中的serializedTask提供的
- 具体要运行的Task是通过serializedTask中的subbuffer中反序列化的
- Task中依赖的RDD,Dependency是从BlockManager从Driver的Block块中获取进行反序列化
- ShuffleMapTask里依赖的的RDD是ShuffledRDD的前一个RDD,而Dependency就是ShuffleDependency
Spark Core(三)Executor上是如何launch task(转载)的更多相关文章
- Spark Core(四)用LogQuery的例子来说明Executor是如何运算RDD的算子(转载)
1. 究竟是怎么运行的? 很多的博客里大量的讲了什么是RDD, Dependency, Shuffle.......但是究竟那些Executor是怎么运行你提交的代码段的? 下面是一个日志分析的例子, ...
- Spark 3.x Spark Core详解 & 性能优化
Spark Core 1. 概述 Spark 是一种基于内存的快速.通用.可扩展的大数据分析计算引擎 1.1 Hadoop vs Spark 上面流程对应Hadoop的处理流程,下面对应着Spark的 ...
- SparkSQL 与 Spark Core的关系
不多说,直接上干货! SparkSQL 与 Spark Core的关系 Spark SQL构建在Spark Core之上,专门用来处理结构化数据(不仅仅是SQL). Spark SQL在Spark C ...
- 大数据:Spark Core(二)Driver上的Task的生成、分配、调度
1. 什么是Task? 在前面的章节里描写叙述过几个角色,Driver(Client),Master,Worker(Executor),Driver会提交Application到Master进行Wor ...
- Spark Core(二)Driver上的Task的生成、分配、调度(转载)
1. 什么是Task? 在前面的章节里描述过几个角色,Driver(Client),Master,Worker(Executor),Driver会提交Application到Master进行Worke ...
- 上万字详解Spark Core(建议收藏)
先来一个问题,也是面试中常问的: Spark为什么会流行? 原因1:优秀的数据模型和丰富计算抽象 Spark 产生之前,已经有MapReduce这类非常成熟的计算系统存在了,并提供了高层次的API(m ...
- spark执行在yarn上executor内存不足异常ERROR YarnScheduler: Lost executor 542 on host-bigdata3: Container marked as failed: container_e40_1550646084627_1007653_01_000546 on host: host-bigdata3. Exit status: 143.
当spark跑在yarn上时 单个executor执行时,数据量过大时会导致executor的memory不足而使得rdd 最后lost,最终导致任务执行失败 其中会抛出如图异常信息 如图中异常所示 ...
- 【Spark Core】TaskScheduler源代码与任务提交原理浅析2
引言 上一节<TaskScheduler源代码与任务提交原理浅析1>介绍了TaskScheduler的创建过程,在这一节中,我将承接<Stage生成和Stage源代码浅析>中的 ...
- 【Spark Core】任务运行机制和Task源代码浅析1
引言 上一小节<TaskScheduler源代码与任务提交原理浅析2>介绍了Driver側将Stage进行划分.依据Executor闲置情况分发任务,终于通过DriverActor向exe ...
随机推荐
- 【转载】经典.net面试题目【为了笔试。。。。。】
. 简述 private. protected. public. internal 修饰符的访问权限. 答 . private : 私有成员, 在类的内部才可以访问. protected : 保护成员 ...
- IOS设计模式第七篇之观察者设计模式
版权声明:原创作品,谢绝转载!否则将追究法律责任. 观察者设计模式 在观察者设计模式里面,一个对象通知其他的对象一些状态的改变.涉及这些对象不需要知道另一个对象---因此鼓励解耦设计模式.这个设计模式 ...
- 怎样更改SQL Server 2008的身份验证方式
大家都知道sql server 有两种登录验证方式,即sql server验证方式和windows验证方式,但是sql server默认的是windows登录验证方式,我们如何启用sql server ...
- 【大数据系列】windows搭建hadoop开发环境
一.安装JDK配置环境变量 已经安装略过 二.安装eclipse 已经安装略过 三.安装Ant 1.下载http://ant.apache.org/bindownload.cgi 2.解压 3.配置A ...
- CSS+transform画动态表情
先给大家看下画完后是什么样子: 代码看这里: html代码: <body> <div class="emoji emoji_like"> <div c ...
- Mysql 忘记 root密码解决
1 stop mysql Ubuntu/Debian: sudo /etc/init.d/mysql stop CentOs: sudo /etc/init.d/mysqld stop 2 启动saf ...
- 分布式文件系统FastDFS架构剖析
ps.本文来自于网络 一.什么是FastDfs FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载)等,解决了大容量存储和负载 ...
- 【CF884F】Anti-Palindromize 费用流
[CF884F]Anti-Palindromize 题意:定义一个串是反回文的,当且仅当对于1<=i<=len,$a_i!=a_{len-i+1}$. 现在给出一个长度为n的串S(n是偶数 ...
- PHP将富文本内容去除各类样式图片等只保留txt文本内容(作用于SEO的description)
1.从数据库读取富文本内容样式如下: <p style=";text-indent: 0;padding: 0;line-height: 26px"><span ...
- Python3中关于下划线变量和命名的总结
变量 #!-*-coding:utf-8-*- #__author__ = 'ecaoyng' # # 变量 #_xxx,单下划线开头的变量,标明是一个受保护(protected)的变量,原则上不允许 ...