本課主題

  • 什么是 Spark 的天堂之门
  • Spark 天堂之门到底在那里
  • Spark 天堂之门源码鉴赏

引言

我说的 Spark 天堂之门就是SparkContext,这篇文章会从 SparkContext 创建3大核心对象 TaskSchedulerImpl、DAGScheduler 和 SchedulerBackend 开始到注册给 Master 这个过程中的源码鉴赏,SparkContext 是整个 Spark 程序通往集群的唯一通道,它是程序起点,也是程序终点,所以我把它称之为天堂之门,看过 Spark HelloWorld 程序的朋友都知道,你在程序的开头必需先定义SparkContext、接著调用 SparkContext 的方法,比如说 sc.textFile(file),最后也会调用 sc.stop( ) 来退出应用程序。现在我们就来看看 SparkContext 里面到底有什么密码,以及为什么它会被称为天堂之门。希望这篇文章能为读者带出以下的启发:

  • 了解在 SparkContext 内部创建了那些实例对象以及如何创建
  • 了解真正是那个实例对象向 Master 注册以及如何注册

什么是 Spark 的天堂之门

  1. Spark 程序在运行的时候分为 DriverExecutor 两部分
  2. Spark 程序编写是基于 SparkContext 的,具体来说包含两方面
    1. Spark 编程的核心 基础-RDD 是由 SparkContext 来最初创建的(第一个RDD一定是由 SparkContext 来创建的)
    2. Spark 程序的调度优化也是基于 SparkContext,首先进行调度优化。
  3. Spark 程序的注册时通过 SparkContext 实例化时候生产的对象来完成的(其实是 SchedulerBackend 来注册程序)
  4. Spark 程序在运行的时候要通过 Cluster Manager 获取具体的计算资源,计算资源获取也是通过 SparkContext 产生的对象来申请的(其实是 SchedulerBackend 来获取计算资源的)
  5. SparkContext 崩溃或者结束的时候整个 Spark 程序也结束啦!

Spark 天堂之门到底在那里

运行一个程序,你会看见 SparkContext 从程序开始到结束都有它的身影,SparkContext 是 Spark 应用程序的核心呀!

[下图是一个 HelloWord 应用程序在 IDEA 中的运行状况]

Spark 天堂之门源码鉴赏

这次主要是看当提交Spark程序后,在 SparkContext 实例化的过程中,里面会创建多少个核心实例来为应用程序完成注冊,SparkContext 最主要的是实例化 TaskSchedulerImpl。

[下图是 SparkContext 在创建核心对象后的流程图]

  1. SparkContext 構建的頂級三大核心:DAGSchedulerTaskScheduler, SchedulerBackend,其中:
    • DAGScheduler 是面向 Job 的 Stage 的高層調度器;
    • TaskScheduler 是一個接口,是低層調度器,根據具體的 ClusterManager 的不同會有不同的實現,Standalone 模式下具體的實現 TaskSchedulerImpl;
    • SchedulerBackend 是一個接口,根據具體的 ClusterManager 的不同會有不同的實現,Standalone 模式下具體的實現是SparkDeploySchedulerBackend
  2. 從整個程序運行的角度來講,SparkContext 包含四大核心對象:DAGSchedulerTaskScheduler, SchedulerBackend, MapOutputTrackerMaster
  3. SparkDeploySchedulerBackend 有三大核心功能:
    • 負責與 Master 連接注冊當前程序 RegisterWithMaster
    • 接收集群中為當前應用程序而分配的計算資源 Executor 的注冊並管理 Executors;
    • 負責發送 Task 到具體的 Executor 執行

補充說明的是 SparkDeploySchedulerBackend 是被 TaskSchedulerImpl 來管理的!

创建 SparkContext 的核心对象
  • 程序一开始运行时会实例化 SparkContext 里的东西,所以不在方法里的成员都会被实例化!一开始实例化的时候第一个关键的代码是 createTaskScheduler,它是位于 SparkContext 的 Primary Constructor 中,当它实例化时会直接被调用,这个方法返回的是 taskScheduler 和 dagScheduler 的实例,然后基于这个内容又构建了 DAGScheduler,然后调用 taskScheduler 的 start( ) 方法,要先创建taskScheduler然后再创建 dagScheduler,因为taskScheduler是受dagScheduler管理的。
    [下图是 SparkContext.scala 中的创建 schedulerBackend 和 taskSchdulerImpl 的实例对象]
  • 调用 createTaskSchedule,这个方法创建了 TaskSchdulerImpl 和 SparkDeploySchedulerBackend,接受第一个参数是 SparkContext 对象本身,然后是字符串,(这也是你平时转入 master 里的字符串)
    [下图是 HelloSpark.scala 中创建 SparkConf 和 SparkContext 的上下文信息]

    [下图是 SparkContext.scala 中的 createTaskScheduler 方法]
  • 它会判断一下你的 master 是什么然后具体进行不同的操作!假设我们是Spark 集群模式,它会:
    [下图是 SparkContext.scala 中的 SparkMasterRegex 静态对象]
  • 创建 TaskSchedulerImpl 实例然后把 SparkContext 传进去;
  • 匹配集群中 master 的地址 e.g. spark://
  • 创建 SparkDeploySchedulerBackend 实例,然后把 taskScheduler (这里是 TaskSchedulerImpl)、SparkContext 和 master 地址信息传进去;
  • 调用 taskScheduler (这里是 TaskSchedulerImpl) 的 initialize 方法 最后返回 (SparkDeploySchedulerBackend, TaskSchedulerImpl) 的实例对象
  • SparkDeploySchedulerBackend 是被 TaskSchedulerImpl 來管理的,所以这里要首先把 scheduler 创建,然后把 scheduler 的实例传进去。
    [下图是 SparkContext.scala 中的调用模式匹配 SPARK_REGEX 的处理逻辑]
  • Task 默认失败后重新启动次数为 4 次
    [下图是 TaskSchedulerImpl.scala 中的类和主构造器的调用方法]

TaskSchedulerImpl.initialize( )方法是

  • 创建一个 Pool 来初定义资源分布的模式 Scheduling Mode,默认是先进先出的 模式。

调用 taskScheduler 的 start( ) 方法

  • 在这个方法中再调用 backend (SparkDeploySchedulerBackend) 的 start( ) 方法。

  • 當通過 SparkDeploySchedulerBackend 注冊程序給 Master 的時候會把以上的 command 提交給 Master 
CoarseGrainedExecutorBackend
  • Master 發指令給 Worker 去啟動 Executor 所有的進程的時候加載的 Main 方法所在的入口類就是 command 中的 CoarseGrainedExecutorBackend,當然你可以實現自己的 ExecutorBackend,在 CoarseGrainedExecutorBackend 中啟動 Executor (Executor 是先注冊再實例化),Executor 通過线程池並發執行 Task。

  • 这里调用了它的 run 方法


  • 注冊成功后再实例化
SparkDeploySchedulerBackend 的 start 方法内幕
  • 然后创建一个很重要的对象,AppClient 对象,然后调用它的 client (AppClient) 的 start( ) 方法,创建一个 ClientEndpoint 对象。

  • 它是一个 RpcEndPoint,然后接下来的故事就是向 Master 注冊,首先调用自己的 onStart 方法
  • 然后再调用 registerWithMaster 方法
  • 从 registerWithMaster 调用 tryRegisterAllMasters,开一条新的线程来注冊,然后发送一条信息(RegisterApplication 的case class ) 给 Master,注冊是通过 Thread 来完成的。


    ApplicationDescription 的 case class
Master 接受程序的注冊
  • Master 收到了这个信息便开始注冊,注冊后最后再次调用 schedule( ) 方法

总结

SparkContext 开启了天堂之门:Spark 程序是通过 SparkContext 发布到 Spark集群的SparkContext 导演了天堂世界:Spark 程序运行都是在 SparkContext 为核心的调度器的指挥下进行的:SparkContext 关闭了天堂之门:SparkContext 崩溃或者结束的是偶整个 Spark 程序也结束啦!

 
 

參考資料

资料来源来至 DT大数据梦工厂 大数据传奇行动 第28课:Spark天堂之门解密视频

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

[Spark内核] 第28课:Spark天堂之门解密的更多相关文章

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

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

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

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

  3. [Spark内核] 第38课:BlockManager架构原理、运行流程图和源码解密

    本课主题 BlockManager 运行實例 BlockManager 原理流程图 BlockManager 源码解析 引言 BlockManager 是管理整个Spark运行时的数据读写的,当然也包 ...

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

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

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

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

  6. [Spark内核] 第29课:Master HA彻底解密

    本课主题 Master HA 解析 Master HA 解析源码分享 [引言部份:你希望读者看完这篇博客后有那些启发.学到什么样的知识点] 更新中...... Master HA 解析 生产环境下一般 ...

  7. [Spark内核] 第30课:Master的注册机制和状态管理解密

    本課主題 Master 接收 Worker, Driver, Application Master 处理 Driver 狀态变换 Master 处理 Executor 狀态变换 [引言部份:你希望读者 ...

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

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

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

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

随机推荐

  1. 赵雅智:service与訪问者之间进行通信,数据交换

    服务类 中间人:service服务中的bind对象 创建中间人并通过onBinder方法的return暴露出去 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQ ...

  2. JavaScript必知的特性(继承)

    多数人在学习JavaScript的时候.都是做Web的时候.须要表单验证.或者是一些简单的DOM操作,如同我上篇所讲.处在一个"辅助"的地位. 处在"辅助"地位 ...

  3. 【SqlServer系列】JSON数据

    1   概述 本文将结合MSDN简要概述JSON数据. 2   具体内容 JSON 是一种流行的数据格式,用于在现代 Web 和移动应用程序中交换数据. JSON 还可用于在 Microsoft Az ...

  4. Java中进制的转换函数

    十进制转成十六进制: Integer.toHexString(int i) 十进制转成八进制 Integer.toOctalString(int i) 十进制转成二进制 Integer.toBinar ...

  5. 实现我博客旁边的线条效果 html canvas-nest.js 源码

    canvas-nest.js 这个js文件可以用来实现炫酷的线条与鼠标进行交互的功能,具体效果如图所示 js具体源码如下: /** * Copyright (c) 2016 hustcc * Lice ...

  6. Hibernate--使用xml配置映射关系

    写在前面: 配置实体类与数据库的映射关系,有两种方式: 1.使用*.hbm.xml  2.使用@注解 二:xml的配置方式: eg:员工的xml配置文件: <?xml version=" ...

  7. 【python】字符串变量赋值时字符串可用单或双引号

    >>> name='萧峰' >>> print(name) 萧峰 >>> name="独孤求败" >>> p ...

  8. JaveScript运算符(JS知识点归纳三)

    JaveScript中有许多的运算符,在这里就只说明一些需要注意的. 01 一元运算符 一元:指的是参与运算的操作数只有一个 最经常使用的是++   -- 计算规则: ++/-- 前置于操作数的时候 ...

  9. 33 款主宰 2017 iOS 开发的开源库

    推荐一篇文章 改文章汇聚了现在主流的一些三方框架,很值得一看 https://mp.weixin.qq.com/s/ICodliohtzbmA-eLKRFT-Q

  10. Struts2学习---拦截器+struts的工作流程+struts声明式异常处理

    这一节我们来看看拦截器,在讲这个之前我是准备先看struts的声明式异常处理的,但是我发现这个声明式异常处理就是由拦截器实现的,所以就将拦截器的内容放到了前面. 这一节的内容是这样的: 拦截器的介绍 ...