Executor原理剖析与源码分析
来源:互联网 发布:网络行为管理设备 编辑:程序博客网 时间:2024/06/06 01:10
版本:spark2.1.0
1、work中为application启动的executor,实际上是启动了CoarseGrainedExecutorBackend进程
private[spark] object CoarseGrainedExecutorBackend extends Logging { private def run( driverUrl: String, executorId: String, hostname: String, cores: Int, appId: String, workerUrl: Option[String], userClassPath: Seq[URL])2、获取driver 的actor,向driver发送RegisterExecutor信息
override def onStart() { logInfo("Connecting to driver: " + driverUrl) rpcEnv.asyncSetupEndpointRefByURI(driverUrl).flatMap { ref => //获取driver 的actor driver = Some(ref) //向driver发送RegisterExecutor信息 ref.ask[Boolean](RegisterExecutor(executorId, self, hostname, cores, extractLogUrls)) }(ThreadUtils.sameThread).onComplete { // This is a very fast action so we can use "ThreadUtils.sameThread" case Success(msg) => // Always receive `true`. Just ignore it case Failure(e) => exitExecutor(1, s"Cannot register with driver: $driverUrl", e, notifyDriver = false) }(ThreadUtils.sameThread) }3、driver注册executor成功之后,会发送RegisteredExecutor消息
此时CoarseGrainedExecutorBackend会创建Executor执行句柄,大部分的功能都是通过Executor实现的
override def receive: PartialFunction[Any, Unit] = { case RegisteredExecutor => logInfo("Successfully registered with driver") try { executor = new Executor(executorId, hostname, env, userClassPath, isLocal = false) } catch { case NonFatal(e) => exitExecutor(1, "Unable to create executor due to " + e.getMessage, e) } case RegisterExecutorFailed(message) => exitExecutor(1, "Slave registration failed: " + message)4、启动task,反序列化task,调用Executor执行器的launchTask()启动一个task
//启动task case LaunchTask(data) => if (executor == null) { exitExecutor(1, "Received LaunchTask command but executor was null") } else { //反序列化task val taskDesc = ser.deserialize[TaskDescription](data.value) logInfo("Got assigned task " + taskDesc.taskId)调用Executor执行器的launchTask()启动一个task executor.launchTask(this, taskId = taskDesc.taskId, attemptNumber = taskDesc.attemptNumber, taskDesc.name, taskDesc.serializedTask) }
5、对每个task都会创建一个TaskRunner,将TaskRunner放入内存缓存中
将task封装在一个线程中(TaskRunner),将线程丢入线程池中,然后执行
线程池是是自动实现了排队机制的
def launchTask( context: ExecutorBackend, taskId: Long, attemptNumber: Int, taskName: String, serializedTask: ByteBuffer): Unit = { //对每个task都会创建一个TaskRunner val tr = new TaskRunner(context, taskId = taskId, attemptNumber = attemptNumber, taskName, serializedTask) //将TaskRunner放入内存缓存中, runningTasks.put(taskId, tr)//将task封装在一个线程中(TaskRunner),将线程丢入线程池中,然后执行//线程池是是自动实现了排队机制的, threadPool.execute(tr) }
下节将分析task的具体被执行的原理
阅读全文
0 0
- Executor原理剖析与源码分析
- Spark2.2 Executor原理剖析及源码分析
- Worker原理剖析与源码分析
- DAGScheduler原理剖析与源码分析
- TaskScheduler原理剖析与源码分析
- Shuffle原理剖析与源码分析
- CacheManager原理剖析与源码分析
- BlockManager原理剖析与源码分析
- 【Java8源码分析】线程池-Executor与ExecutorService的全面剖析
- Master原理剖析与源码分析:主备切换机制原理剖析与源码分析
- Master原理剖析与源码分析:注册机制原理剖析与源码分析
- Master原理剖析与源码分析:Master状态改变处理机制原理剖析与源码分析
- 6.job触发流程原理剖析与源码分析
- job触发流程原理剖析与源码分析
- Spark2.2 job触发流程原理剖析与源码分析
- Spark2.2 TaskScheduler原理剖析与源码分析
- 8.Executor源码分析与Task源码分析
- Spark内核源码深度剖析:SparkContext原理剖析与源码分析
- 机器学习实战-SVD与特征值分解的理论推导及SVD在推荐系统中的应用
- filter对页面内容敏感词进行替换处理
- PHP中利用PHPMailer配合QQ邮箱实现发邮件
- OJ输入格式Type1
- “我会对你负责的。”
- Executor原理剖析与源码分析
- Spring-Boot 邮件简单使用
- php操作redis实例
- Java并发编程(三)Java内存模型及volatile
- lintcode滑动窗口最大值
- js时间戳转换为日期格式
- Java 开发环境配置
- python遍历文件夹,指定遍历深度与忽略目录
- angular获取各种service