本课主题

  • Task执行内幕与结果处理解密

引言

这一章我们主要关心的是 Task 是怎样被计算的以及结果是怎么被处理的

  • 了解 Task 是怎样被计算的以及结果是怎么被处理的

Task 执行原理流程图

[下图是Task执行原理流程图]

  1. Executor 会通过 TaskRunner 在 ThreadPool 来运行具体的 Task,TaskRunner 内部会做一些准备的工作,例如反序例化 Task,然后通过网络获取需要的文件、Jar等
  2. 运行 Thread 的 run 方法,导致 Task 的 runTask 被调用来执行具体的业务逻辑处理
  3. 在Task 的 runTask内部会调用 RDD 的 iterator( ) 方法,该方法就是我们针对当前 Task 所对应的 Partition 进行计算的关键之所在,在处理内部会迭代 Partition 的元素并交给我们先定义的 Function 进行处理
    • ShuffleMapTask: ShuffleMapTask 在计算具体的 Partition 之后实际上会通过 ShuffleManager 获得的 ShuffleWriter 把当前 Task 计算的数据具体 ShuffleManger 的实现来写入到具体的文件。操作完成后会把 MapStatus 发送给 DAGScheduler; (把 MapStatus 汇报给 MapOutputTracker)
    • ResultTask: 根据前面 Stage 的执行结果进行 Shuffle 产生整个 Job 最后的结果;(MapOutputTracker 會把 ShuffleMapTask 執行結果交給 ResultTask)

Task 执行内幕源码解密

  1. 当 Driver 中的 CoarseGrainedSchedulerBackend 给 CoarseGrainedExecutorBackend 发送 LaunchTask 之后,CoarseGrainedExecutorBackend 在收到 LaunchTask 消息后,首先会判断一下有没有 Executor,没有的话直接退出和打印出提示信息,有的话会反序例化 TaskDescription,在执行具体的业务逻辑前会进行3次反序例化,第一个是 taskDescription,第二个是任务 Task 本身进行反序例化,还有的是RDD 的反序例化。
    [下图是 CoarseGrainedExecutorBackend.scala 接收 LaunchTask case class 信息后的逻辑]

    然后再发 LaunchTask 消息,里面会创建一个 TaskRunner,然后把它交给一个 runningTasks 的数据结构中,然后交给线程池去执行 Thread Pool。
    [下图是 Executor.scala 中的 launchTask 方法]
  2. Executor 会通过 TaskRunner 在ThreadPool 来运行具体的 Task,在 TaskRunner 的 run( )方法中首先会通过调用 stateUpdate 给 Driver 发信息汇报自己的状态,说明自己的RUNNING 状态。
    [下图是 Executor.scala 中的 TaskRunner 类]

    [下图是 Executor.scala 中的 run 方法]

    [下图是 ExecutorBackend.scala 中的 statusUpdate 方法]
  3. TaskRunner 内部会做一些准备的工作,例如反序例化 Task 的依赖,这个反序例化得出一个 Tuple,然后通过网络获取需要的文件、Jar等;
    [下图是在 Executor.scala 中 run 方法内部具体的代码实现]
  4. 在同一个 Stage 的内部需要共享资源。在同一个 Stage 中我们 ExecutorBackend 会有很多并发线程,此时它们所依赖的 Jar 跟文件肯定是一样的,每一个 TaskRunner 运行的时候都会运行在线程中,这个方法会被多个线程去调,所以线程需要一个加锁,而这个方法是有全区中的。这主要是要防止资源竞争。下载一切这个 Task 需要的 Jar 文件,我们通 Executor 在不同的线程中共享全区资源。
    [下图是 Executor.scala 中的 updateDependencies 方法]

  5. 在 Task 的 runTask 内部会调用 RDD 的 iterator( ) 方法,该方法就是我们针对当前 Task 所对应的 Partition 进行计算的关键之所在,在处理内部会迭代 Partition 的元素并交给我们先定义的 Function 进行处理对于 ShuffleMapTask,首先要对 RDD 以及其他的依赖关系进行反序例化:
    [下图是 Executor.scala 中 run 方法内部具体的代码实现]

    [下图是 Task.scala 中的 run 方法]

    因为 Task 是一个 abstract class,它的子类是 ShuffleMapTask 或者是 ResultsMapTask,是乎我们当前的 Task 是那个类型。
    [下图是 ShuffleMapTask.scala 中的 runTask 方法]

    [下图是 RDD.scala 中的 iterator 方法]

    [下图是 RDD.scala 中的 computeOrReadCheckpoint 方法]

    最终计算会调用 RDD 的 compute 的方法具体计算的时候有具体的 RDD,例如 MapPartitionsRDD.compute,其中的 f 就是在当前 Stage 计算具体 Partition 的业务逻辑代码。
    [下图是 RDD.scala 中的 compute 方法]

    [下图是 MapPartitionsRDD.scala 中的 compute 方法]
  6. 调用反序例化后的 Task.run 方法来执行任务并获得执行结果,其中 Task 的 run 方法调用的时候会导致 Task 的抽象方法 runTask 的调用
    [下图是 Executor.scala 中 run 方法内部具体的代码实现]

  7. 把执行结果序例化
    [下图是 Executor.scala 中 run 方法内部具体的代码实现]
  8. 运行 Thread 的 run 方法,导致 Task 的 runTask 被调用来执行具体的业务逻辑处理
  9. 对于 ResultTask
    [下图是 ResultsMapTask.scala 中的 runTask 方法]
  10. 在 Spark 中 AkaFrameSize 是 128MB,所以可以扩播非常大的任务,而任务
  11. 并根据大小判断不同的结果传回给 Driver 的方式
  12. CoraseGrainedExectorBackend 给 DriverEndpoint 发送 StatusUpdate 来传执行结果
    [下图是 Executor.scala 中 run 方法内部具体的代码实现]

    [下图是 CoraseGrainedExectorBackend.scala 中 statusUpdate 方法]

    [下图是 DriveEndPoint.scala 中 receive 方法]
  13. DriverEndpoint 会把执行结果传给 TaskSchedulerImpl 处理,然后交给 TaskResultGetter 去分别处理执行成功和失败时候的不同情况,然后告X DAGScheduler 任务处理结的情况重
    [下图是 TaskSchedulerImpl.scala 中 statusUpdate 方法]

    [下图是 TaskResultsGetter.scala 中 handleSuccessfulTask 方法]

    [下图是 TaskSchedulerImpl.scala 中 handleSuccessfulTask 方法]

    [下图是 TaskSetManager.scala 中 handleSuccessfulTask 方法]

參考資料

资料来源来至 DT大数据梦工厂 大数据传奇行动 第37课:Task执行内幕与结果处理解密

Spark源码图片取自于 Spark 1.6.0版本

[Spark内核] 第37课:Task执行内幕与结果处理解密的更多相关文章

  1. Task执行内幕与结果处理解密

    本课主题 Task执行内幕与结果处理解密 引言 这一章我们主要关心的是 Task 是怎样被计算的以及结果是怎么被处理的 了解 Task 是怎样被计算的以及结果是怎么被处理的 Task 执行原理流程图 ...

  2. [Spark内核] 第36课:TaskScheduler内幕天机解密:Spark shell案例运行日志详解、TaskScheduler和SchedulerBackend、FIFO与FAIR、Task运行时本地性算法详解等

    本課主題 通过 Spark-shell 窥探程序运行时的状况 TaskScheduler 与 SchedulerBackend 之间的关系 FIFO 与 FAIR 两种调度模式彻底解密 Task 数据 ...

  3. [Spark内核] 第33课:Spark Executor内幕彻底解密:Executor工作原理图、ExecutorBackend注册源码解密、Executor实例化内幕、Executor具体工作内幕

    本課主題 Spark Executor 工作原理图 ExecutorBackend 注册源码鉴赏和 Executor 实例化内幕 Executor 具体是如何工作的 [引言部份:你希望读者看完这篇博客 ...

  4. [Spark内核] 第34课:Stage划分和Task最佳位置算法源码彻底解密

    本課主題 Job Stage 划分算法解密 Task 最佳位置算法實現解密 引言 作业调度的划分算法以及 Task 的最佳位置的算法,因为 Stage 的划分是DAGScheduler 工作的核心,这 ...

  5. [Spark内核] 第35课:打通 Spark 系统运行内幕机制循环流程

    本课主题 打通 Spark 系统运行内幕机制循环流程 引言 通过 DAGScheduelr 面向整个 Job,然后划分成不同的 Stage,Stage 是從后往前划分的,执行的时候是從前往后执行的,每 ...

  6. [Spark内核] 第31课:Spark资源调度分配内幕天机彻底解密:Driver在Cluster模式下的启动、两种不同的资源调度方式源码彻底解析、资源调度内幕总结

    本課主題 Master 资源调度的源码鉴赏 [引言部份:你希望读者看完这篇博客后有那些启发.学到什么样的知识点] 更新中...... 资源调度管理 任务调度与资源是通过 DAGScheduler.Ta ...

  7. [Spark内核] 第28课:Spark天堂之门解密

    本課主題 什么是 Spark 的天堂之门 Spark 天堂之门到底在那里 Spark 天堂之门源码鉴赏 引言 我说的 Spark 天堂之门就是SparkContext,这篇文章会从 SparkCont ...

  8. [Spark内核] 第40课:CacheManager彻底解密:CacheManager运行原理流程图和源码详解

    本课主题 CacheManager 运行原理图 CacheManager 源码解析 CacheManager 运行原理图 [下图是CacheManager的运行原理图] 首先 RDD 是通过 iter ...

  9. [Spark内核] 第32课:Spark Worker原理和源码剖析解密:Worker工作流程图、Worker启动Driver源码解密、Worker启动Executor源码解密等

    本課主題 Spark Worker 原理 Worker 启动 Driver 源码鉴赏 Worker 启动 Executor 源码鉴赏 Worker 与 Master 的交互关系 [引言部份:你希望读者 ...

随机推荐

  1. 两行 CSS 代码实现 PNG 任意颜色赋色技术

    很久之前在张鑫旭大大的博客看到过一篇 PNG格式小图标的CSS任意颜色赋色技术,当时惊为天人,感慨还可以这样玩,私底下也曾多次想过有没有其他方法可以实现. 本方法与上面 ZXX 的方法及流传的使用 f ...

  2. COCOS学习笔记--关于使用cocostudio打安卓包

    我在之前的博客里也写到过,如今cocos引擎提供了一键打包.很方便. 今天正好做个測试,想用引擎的一键打包弄个apk的安卓包.以下就简介一下详细过程和自己的一些理解: 先说一下项目背景,因为我的电脑是 ...

  3. NHibernate之旅(13):初探马上载入机制

    本节内容 引入 马上载入 实例分析 1.一对多关系实例 2.多对多关系实例 结语 引入 通过上一篇的介绍,我们知道了NHibernate中默认的载入机制--延迟载入.其本质就是使用GoF23中代理模式 ...

  4. Spring Boot-------JPA基础及查询规则

    JPA基础及查询规则 JPA JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数 ...

  5. 第五章 使用 SqlSession

    第五章 使用 SqlSession 原文链接; http://www.mybatis.org/spring/zh/sqlsession.html 在 MyBatis 中,你可以使用 SqlSessio ...

  6. 【java】缓冲字符字节输入输出流:java.io.BufferedReader、java.io.BufferedWriter、java.io.BufferedInputStream、java.io.BufferedOutputStream

    BufferedReader最重要,因为有个方法public String readLine() package System输入输出; import java.io.BufferedReader; ...

  7. UIImage类方法总结及UIImage生成方法对比

    http://mp.weixin.qq.com/s/A900w0Y5pGjuaB4j9Os9ww1.UIImage 生成方法的对比 Apple官方的文档为生成一个UIImage对象提供了两种方法: 1 ...

  8. nova创建虚拟机源码分析系列之八 compute创建虚机

    /conductor/api.py _build_instance()  /conductor/rpcapi.py  _build_instance() 1 构造一些数据类型2 修改一些api版本信息 ...

  9. Java NIO (五) 管道 (Pipe)

    Java NIO 管道是2个线程之间的单向数据连接.Pipe有一个source通道和一个sink通道.数据会被写到sink通道,从source通道读取. 如下图: 向管道写数据: 从管道读数据: 1. ...

  10. 微信小程序红包开发 小程序发红包 开发过程中遇到的坑 微信小程序红包接口的

    最近公司在开发一个小程序红包系统,客户抢到红包需要提现.也就是通过小程序来给用户发红包. 小程序如何来发红包呢?于是我想到两个方法. 之前公众号开发一直用了的.一个是红包接口,一个是企业支付接口.一开 ...