SparkContext作为整个Spark的入口,不管是spark、sparkstreaming、spark sql都需要首先创建一个SparkContext对象,然后基于这个SparkContext进行后续RDD的操作;所以很有必要了解下SparkContext在初始化时干了什么事情。

SparkContext初始化过程主要干了如下几件事情:

1、根据SparkContext的构造入参SparkConf创建SparkEnv;

2、初始化SparkUI;

3、创建TaskScheduler;

4、创建DAGScheduler;

5、启动taskScheduler;

通过源代码说明SparkContext初始化的过程

1、创建SparkEnv

private[spark] val env = SparkEnv.create(
conf, "<driver>", conf.get("spark.driver.host"), conf.get("spark.driver.port").toInt,
isDriver = true, isLocal = isLocal, listenerBus = listenerBus)
SparkEnv.set(env)

2、初始化SparkUI

private[spark] val ui = new SparkUI(this)
ui.bind()

3、创建TaskScheduler:根据spark的运行模式创建不同的SchedulerBackend

private[spark] var taskScheduler = SparkContext.createTaskScheduler(this, master)

private def createTaskScheduler(sc: SparkContext, master: String): TaskScheduler = {
val SPARK_REGEX = """spark://(.*)""".r master match {
case SPARK_REGEX(sparkUrl) =>
val scheduler = new TaskSchedulerImpl(sc)
val masterUrls = sparkUrl.split(",").map("spark://" + _)
val backend = new SparkDeploySchedulerBackend(scheduler, sc, masterUrls)
scheduler.initialize(backend) //为TaskSchedulerImpl中的backend变量初始化
scheduler
}
} TaskSchedulerImpl extends TaskScheduler{
var backend: SchedulerBackend = null
def initialize(backend: SchedulerBackend) {
this.backend = backend //将SparkDeploySchedulerBackend赋值给backend变量
rootPool = new Pool("", schedulingMode, 0, 0)
schedulableBuilder = {
schedulingMode match {
case SchedulingMode.FIFO => //先进先出调度
new FIFOSchedulableBuilder(rootPool)
case SchedulingMode.FAIR => //公平调度
new FairSchedulableBuilder(rootPool, conf)
}
}
schedulableBuilder.buildPools()
}
} private[spark] class SparkDeploySchedulerBackend(scheduler: TaskSchedulerImpl,sc: SparkContext,masters: Array[String])
extends CoarseGrainedSchedulerBackend(scheduler, sc.env.actorSystem) with AppClientListener with Logging { }

4、创建DAGScheduler:根据TaskScheduler创建DAGScheduler,用于接收提交过来的job

//根据TaskScheduler创建DAGScheduler,产生eventProcssActor(是DAGSchedule的通信载体,能接收和发送很多消息)
@volatile private[spark] var dagScheduler: DAGScheduler = new DAGScheduler(this)
class DAGScheduler{ def this(sc: SparkContext) = this(sc, sc.taskScheduler) private def initializeEventProcessActor() {
implicit val timeout = Timeout(30 seconds)
val initEventActorReply = dagSchedulerActorSupervisor ? Props(new DAGSchedulerEventProcessActor(this))
eventProcessActor = Await.result(initEventActorReply, timeout.duration).
asInstanceOf[ActorRef]
} initializeEventProcessActor()
}

//详细分析见DAGScheduler篇章
private[scheduler] class DAGSchedulerEventProcessActor(dagScheduler: DAGScheduler)extends Actor with Logging {{ override def preStart() {
dagScheduler.taskScheduler.setDAGScheduler(dagScheduler)
} def receive = {
case JobSubmitted(jobId, rdd, func, partitions, allowLocal, callSite, listener, properties) =>
dagScheduler.handleJobSubmitted(jobId, rdd, func, partitions, allowLocal, callSite,listener, properties)
......
}
}

5、启动taskScheduler

启动taskScheduler的主要目的是启动相应的SchedulerBackend,并判断是否进行推测式执行任务;

在启动TaskScheduler的过程中会创建Application并向Master发起注册请求;

taskScheduler.start()

TaskSchedulerImpl extends TaskScheduler{
var backend: SchedulerBackend = null
override def start() {
backend.start()
//spark.speculation...
}
} private[spark] class SparkDeploySchedulerBackend(scheduler: TaskSchedulerImpl,sc: SparkContext,masters: Array[String])
extends CoarseGrainedSchedulerBackend(scheduler, sc.env.actorSystem) with AppClientListener with Logging {
var client: AppClient = null
val maxCores = conf.getOption("spark.cores.max").map(_.toInt) override def start() {
super.start() //调用CoarseGrainedSchedulerBackend的start()方法
val driverUrl = "akka.tcp://spark@%s:%s/user/%s".format(
conf.get("spark.driver.host"), conf.get("spark.driver.port"),
CoarseGrainedSchedulerBackend.ACTOR_NAME)
val command = Command(
"org.apache.spark.executor.CoarseGrainedExecutorBackend", args, sc.executorEnvs,
classPathEntries, libraryPathEntries, extraJavaOpts)
val sparkHome = sc.getSparkHome()
val appDesc = new ApplicationDescription(sc.appName, maxCores, sc.executorMemory, command,
sparkHome, sc.ui.appUIAddress, sc.eventLogger.map(_.logDir)) client = new AppClient(sc.env.actorSystem, masters, appDesc, this, conf)
client.start()

}
} class CoarseGrainedSchedulerBackend(scheduler: TaskSchedulerImpl, actorSystem: ActorSystem) extends SchedulerBackend with Logging
var driverActor: ActorRef = null
override def start() {
driverActor = actorSystem.actorOf(
Props(new DriverActor(properties)), name = CoarseGrainedSchedulerBackend.ACTOR_NAME)
}
} class ClientActor extends Actor with Logging{
override def preStart() {
registerWithMaster() //向Master注册Application
}
}

CoarseGrainedSchedulerBackend与CoarseGrainedExecutorBackend通信

private[spark] class CoarseGrainedExecutorBackend(driverUrl: String, executorId: String, hostPort: String, cores: Int)
extends Actor with ExecutorBackend with Logging {
var executor: Executor = null
var driver: ActorSelection = null override def preStart() {
logInfo("Connecting to driver: " + driverUrl)
driver = context.actorSelection(driverUrl)
driver ! RegisterExecutor(executorId, hostPort, cores) //注册Executor,接收方是CoarseGrainedSchedulerBackend
context.system.eventStream.subscribe(self, classOf[RemotingLifecycleEvent])
} override def receive = {
case RegisteredExecutor(sparkProperties)
case LaunchTask(taskDesc)
case KillTask(taskId, _, interruptThread)
case StopExecutor
}
}

Spark分析之SparkContext启动过程分析的更多相关文章

  1. Spark分析之Standalone运行过程分析

    一.集群启动过程--启动Master $SPARK_HOME/sbin/start-master.sh start-master.sh脚本关键内容: spark-daemon.sh start org ...

  2. Zico源代码分析:执行启动过程分析和总结

    事实上已经有童鞋对Zico的源代码和执行过程进行了总结,比如:http://www.cnblogs.com/shuaiwang/p/4522905.html.这里我再补充一些内容. 当我们使用mvn ...

  3. Spark Streaming应用启动过程分析

    本文为SparkStreaming源码剖析的第三篇,主要分析SparkStreaming启动过程. 在调用StreamingContext.start方法后,进入JobScheduler.start方 ...

  4. 《深入理解Spark:核心思想与源码分析》——SparkContext的初始化(叔篇)——TaskScheduler的启动

    <深入理解Spark:核心思想与源码分析>一书前言的内容请看链接<深入理解SPARK:核心思想与源码分析>一书正式出版上市 <深入理解Spark:核心思想与源码分析> ...

  5. spark源码阅读--SparkContext启动过程

    ##SparkContext启动过程 基于spark 2.1.0  scala 2.11.8 spark源码的体系结构实在是很庞大,从使用spark-submit脚本提交任务,到向yarn申请容器,启 ...

  6. Disconf源码分析之启动过程分析下(2)

    接上文,下面是第二次扫描的XML配置. <bean id="disconfMgrBean2" class="com.baidu.disconf.client.Dis ...

  7. Linux内核分析(三)内核启动过程分析——构造一个简单的Linux系统

    一.系统的启动(各历史节点) 在最开始的时候,计算机的启动实际上依靠一段二进制码,可以这么理解,他并不是一个真正的计算机启动一道程序.计算机在开始加电的时候几乎是没有任何用处的,因为RAM芯片中包括的 ...

  8. u-boot 源码分析(1) 启动过程分析

    u-boot 源码分析(1) 启动过程分析 文章目录 u-boot 源码分析(1) 启动过程分析 前言 配置 源码结构 api arch board common cmd drivers fs Kbu ...

  9. ASP.Net Core MVC6 RC2 启动过程分析[偏源码分析]

    入口程序 如果做过Web之外开发的人,应该记得这个是标准的Console或者Winform的入口.为什么会这样呢? .NET Web Development and Tools Blog ASP.NE ...

随机推荐

  1. art.dialog 使用说明

    Js代码 2. 传入HTMLElement   备注:1.元素不是复制而是完整移动到对话框中,所以原有的事件与属性都将会保留 2.如果隐藏元素被传入到对话框,会设置display:block属性显示该 ...

  2. 1.1.3 A+B for Input-Output Practice (III)

    A+B for Input-Output Practice (III) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 ...

  3. matplotlib 操作子图(subplot,axes)

    Matplotlib 中文用户指南 3.3 使用 GridSpec 自定义子图位置 ax:matplotlib.axes._subplots.AxesSubplot,的基本操作 ax.set_xtic ...

  4. rar ubuntu

    http://jingyan.baidu.com/article/1612d5004095eee20e1eeeab.html sudo 7z x ***.rar

  5. Android Kernel save defalut config

    /********************************************************************************* * Android Kernel ...

  6. AHK教程 - imsoft.cnblogs

    转自:小弗兰茨 AHK,就是传说中的 Auto Hot Key .什么?没有听说过?那么很正常……它运行在Windows下.总之,AHK可以赋予你对你的电脑的无与伦比的控制力.一些人想要在MM面前展示 ...

  7. 发布网站的时候发现360极速浏览器ie7内核不兼容样式的问题

    引言:  在Web应用的开发过程中,发现若干页面在360的浏览器上显示不正常,而在其他的浏览器上,皆为正常状态,问题出在哪里呢? 问题的提出: Web页面在360的浏览器上,显示不正确. 但是在Fir ...

  8. $.grep()的用法

    grep()方法用于数组元素过滤筛选 grep(array,callback,invert) array:待过滤数组; callback:处理数组中的每个元素,并过滤元素,该函数中包含两个参数,第一个 ...

  9. jquery选择器之属性过滤选择器详解

    代码如下: <style type="text/css">  /*高亮显示*/  .highlight{       } </style> 复制代码代码如下 ...

  10. juc并发工具类之CountDownLatch闭锁

    import java.util.concurrent.CountDownLatch; /** * 闭锁: 在进行某些运算时, 只有其他所有线程的运算全部完成,当前运算才继续执行(程序流中加了一道栅栏 ...