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 ...
随机推荐
- sql,去重
distinct SELECT distinct nf FROM BSHGJJK.T_JJ_NY_QSNCJBQK order by nf desc 来自为知笔记(Wiz)
- 第十七篇 make的路径搜索综合实践
本节我们编写路径搜索相关的makefile,具体需求如下: 1.工程项目中不希望源码文件夹在编译时被改动(只读文件夹). 2.在编译时自动创建文件夹(build)用于存放编译结果. 3.编译过 ...
- pip source
linux版本 sudo vim .pip/pip.conf[global]index-url = http://pypi.douban.com/simple[install]trusted-host ...
- ULINK2配置
先要安装ULINK2的驱动 如果还没有检测到驱动的话,下个驱动人生,应该就行了.反正我就是这样弄成的^-^. 然后就是配置了 这样就可以下载了.
- BZOJ3052: [wc2013]糖果公园【树上带修莫队】
Description Input Output Sample Input Sample Input Sample Output 84 131 27 84 HINT 思路 非常模板的树上带修莫队 真的 ...
- test20181017 B君的第二题
题意 分析 考场50分 旁边的L君告诉我,求的就是非升子序列的个数,于是写了个树状数组. 但是\(\mod{2333} > 0\)还需要组合数中没有2333的倍数,所以实际上只得了\(a_i \ ...
- (精)字符串,map -> json对象->map(初学者必读)
import java.util.LinkedList; import java.util.*; import java.util.ListIterator; import net.sf.json.J ...
- jquery选择器之属性过滤选择器详解
代码如下: <style type="text/css"> /*高亮显示*/ .highlight{ } </style> 复制代码代码如下 ...
- PythonWeb开发教程(一),开发之前需要准备什么
什么是web开发呢,其实就是开发一个网站了.那开发网站需要用到哪些知识呢 1.python基础,因为用python开发的,所以python指定要会,最起码你也得会条件判断,循环,函数,类这些知识: 2 ...
- MQ的不足
调用方实时依赖执行结果的业务场景,请使用调用,而不是MQ.MQ是互联网分层架构中的解耦利器,那所有通讯都使用MQ岂不是很好?这是一个严重的误区,调用与被调用的关系,是无法被MQ取代的.比如用户登录场景 ...