Spark分析之SparkContext启动过程分析
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启动过程分析的更多相关文章
- Spark分析之Standalone运行过程分析
一.集群启动过程--启动Master $SPARK_HOME/sbin/start-master.sh start-master.sh脚本关键内容: spark-daemon.sh start org ...
- Zico源代码分析:执行启动过程分析和总结
事实上已经有童鞋对Zico的源代码和执行过程进行了总结,比如:http://www.cnblogs.com/shuaiwang/p/4522905.html.这里我再补充一些内容. 当我们使用mvn ...
- Spark Streaming应用启动过程分析
本文为SparkStreaming源码剖析的第三篇,主要分析SparkStreaming启动过程. 在调用StreamingContext.start方法后,进入JobScheduler.start方 ...
- 《深入理解Spark:核心思想与源码分析》——SparkContext的初始化(叔篇)——TaskScheduler的启动
<深入理解Spark:核心思想与源码分析>一书前言的内容请看链接<深入理解SPARK:核心思想与源码分析>一书正式出版上市 <深入理解Spark:核心思想与源码分析> ...
- spark源码阅读--SparkContext启动过程
##SparkContext启动过程 基于spark 2.1.0 scala 2.11.8 spark源码的体系结构实在是很庞大,从使用spark-submit脚本提交任务,到向yarn申请容器,启 ...
- Disconf源码分析之启动过程分析下(2)
接上文,下面是第二次扫描的XML配置. <bean id="disconfMgrBean2" class="com.baidu.disconf.client.Dis ...
- Linux内核分析(三)内核启动过程分析——构造一个简单的Linux系统
一.系统的启动(各历史节点) 在最开始的时候,计算机的启动实际上依靠一段二进制码,可以这么理解,他并不是一个真正的计算机启动一道程序.计算机在开始加电的时候几乎是没有任何用处的,因为RAM芯片中包括的 ...
- u-boot 源码分析(1) 启动过程分析
u-boot 源码分析(1) 启动过程分析 文章目录 u-boot 源码分析(1) 启动过程分析 前言 配置 源码结构 api arch board common cmd drivers fs Kbu ...
- ASP.Net Core MVC6 RC2 启动过程分析[偏源码分析]
入口程序 如果做过Web之外开发的人,应该记得这个是标准的Console或者Winform的入口.为什么会这样呢? .NET Web Development and Tools Blog ASP.NE ...
随机推荐
- JMeter传递JSON数据
步骤: 1.添加线程组.HTTP请求默认值.察看结果树等参考<JMeter实现bugfree登录接口测试>.这里不再赘述. 2.添加HTTP请求 在Body Data中写上输入的参数.参数 ...
- Java第十次作业--多线程
一.学习要点 认真看书并查阅相关资料,掌握以下内容: 理解进程和线程的区别 掌握Java多线程的两种实现方式和区别 理解线程对象的生命周期 熟悉线程控制的基本方法 掌握Java线程的同步机制 理解多线 ...
- RESTful API 学习
/********************************************************************************* * RESTful API 学习 ...
- Buildroot Qt 5
/********************************************************************************* * Buildroot Qt 5 ...
- HDU 3746:Cyclic Nacklace(KMP循环节)
Cyclic Nacklace Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- Java8 (Function,Consumer,Predicate,Supplier)详解
1. https://blog.csdn.net/lzm18064126848/article/details/70199769 1.1 https://blog.csdn.net/turbo_zon ...
- 【maven】Maven中的dependencyManagement
dependencyManagement使用简介 Maven中的dependencyManagement元素提供了一种管理依赖版本号的方式.在dependencyManagement元素中声明所依赖的 ...
- test20180919 区间最大值
题意 分析 我们将所有修改操作的左右端点都拿出来混合着排序. 然后扫描线一样扫描每个端点,维护一个堆储存当前最大值,然后就可以把这些修改操作分成O(m) 个不相交的区间,各自贡献独立. 复杂度为\(O ...
- 一张图解释java跨平台
- Monocular 集成harbor helm 仓库
harbor 已经支持了helm 仓库(使用chartmuseum),Monocular 是一个不错的helm 仓库可视化工具 测试Monocular集成harbor 私服功能 使用docker- ...