1、编写的一个WordCount的例子,其中有 :
val conf = new SparkConf() //创建SparkConf对象
conf.setAppName("Wow,My First Spark App!") //设置应用程序的名称,
conf.setMaster("local") // 程序在本地运行
val sc = new SparkContext(conf)
2、 val sc = new SparkContext(conf) 这里开始迈入天堂之门!!!
new SparkContext 新建一个SparkContext实例,class SparkContext(config: SparkConf){}类中的语句除了方法以外,所有的语句都会执行!
因此会初始化一大堆的属性(略过),及执行class SparkContext中所有的语句!
3、让我们来看一看class SparkContext(config:SparkConf){}天堂之门这个类
https://github.com/apache/spark/blob/master/core/src/main/scala/org/apache/spark/SparkContext.scala
20-67行 import包 略过
123-191行 辅助构造器,传入各种参数的,略过
200-222 一堆属性 ,略过
229-369 定义了一些方法,略过
371行开始了:
执行语句,给一些值赋值,略过
448行 有给UI页面的赋值,绑定
Some(SparkUI.createLiveUI(this, _conf, listenerBus, _jobProgressListener,
。。。。。。
_ui.foreach(_.bind())
493行: 在 createTaskScheduler之前,注册HeartbeatReceiver
重点来了!!!!!天堂的钥匙在这里!!调用createTaskScheduler方法
499行:
val (sched, ts) = SparkContext.createTaskScheduler(this, master)
4、让我们来看一看createTaskScheduler方法
private def createTaskScheduler( | |
sc: SparkContext, | |
master: String): (SchedulerBackend,TaskScheduler) = { | |
import SparkMasterRegex._ |
。。。。。。。
2325行:
我们这里是standlone模式,master匹配这个case SPARK_REGEX(sparkUrl),好的 看一下
case SPARK_REGEX(sparkUrl) => | |
val scheduler = new TaskSchedulerImpl(sc) //新建一个TaskSchedulerImpl | |
val masterUrls = sparkUrl.split(",").map("spark://"+ _) | |
val backend = new SparkDeploySchedulerBackend(scheduler, sc, masterUrls) //新建了SparkDeploySchedulerBackend实例 | |
scheduler.initialize(backend) //接下来看这个了initialize | |
(backend, scheduler) //这里返回了一个元组!!!赋值了499行的val (sched, ts) |
5、天堂之路漫长。。。。。。
接下来看sheduler.initialize 调用的是TaskSchedulerImpl类的 initialize(backend: SchedulerBackend)方法。。。。。
我们看一下
https://github.com/apache/spark/blob/87abcf7df921a5937fdb2bae8bfb30bfabc4970a/core/src/main/scala/org/apache/spark/scheduler/TaskSchedulerImpl.scala
之前新建TaskSchedulerImpl的时侯给schedulingMode变量赋值,
110-116行: 有两种调度模式FIFO 先入先出 Fair 公平调度
private val schedulingModeConf = conf.get("spark.scheduler.mode", "FIFO") | |
val schedulingMode: SchedulingMode = try { | |
SchedulingMode.withName(schedulingModeConf.toUpperCase) |
调用initialize初始化的时候,判断匹配SchedulingMode的值为FIFO还是FAIR,然后
创建ShedulerPool
125行开始
125
def initialize(backend: SchedulerBackend) {
126
this.backend = backend
127
// temporarily set rootPool name to empty
128
rootPool = new Pool("", schedulingMode, 0, 0)
129
schedulableBuilder = {
130
schedulingMode match {
131
case SchedulingMode.FIFO =>
132
new FIFOSchedulableBuilder(rootPool)
133
case SchedulingMode.FAIR =>
134
new FairSchedulableBuilder(rootPool, conf)
135
}
136
}
137
schedulableBuilder.buildPools()
138
}