略微了解Spark源代码的人应该都知道SparkContext,作为整个Project的程序入口,其重要性不言而喻,很多大牛也在源代码分析的文章中对其做了非常多相关的深入分析和解读。这里,结合自己前段时间的阅读体会,与大家共同讨论学习一下Spark的入口对象—天堂之门—SparkContex。

SparkContex位于项目的源代码路径\spark-master\core\src\main\scala\org\apache\spark\SparkContext.scala中,源文件包括SparkContextClasss声明和其伴生对象SparkContextObject。而之所以将SparkContext称为整个程序的入口,原因在于,无论我们是从本地还是HDFS读取文件,总要首先创建一个SparkContext对象,然后基于这个SC对象,展开兴许的RDD对象创建、转换等操作。

在创建SparkContex对象的过程中,进行了一系列的初始化操作,主要包含下面内容:

  1. 加载配置文件SparkConf
  2. 创建SparkEnv
  3. 创建TaskScheduler
  4. 创建DAGScheduler

1、 加载配置文件SparkConf

在SparkConf初始化时,会将相关的配置參数传递给SparkContex,包含master、appName、sparkHome、jars、environment等信息,这里的构造函数有多中表达形式,但最归初始化的结果都是殊途同归,SparkContex获取了全部相关的本地配置和执行时配置信息。

def this(master: String, appName: String, conf: SparkConf) =
this(SparkContext.updatedConf(conf, master, appName)) def this(
master: String,
appName: String,
sparkHome: String = null,
jars: Seq[String] = Nil,
environment: Map[String, String] = Map(),
preferredNodeLocationData: Map[String, Set[SplitInfo]] = Map()) =
{
this(SparkContext.updatedConf(new SparkConf(), master, appName, sparkHome, jars, environment))
this.preferredNodeLocationData = preferredNodeLocationData
}

2、创建SparkEnv

SparkEnv是一个很重要的变量,其内包括了很多Spark执行时的重要组件(变量),包括 MapOutputTracker、ShuffleFetcher、BlockManager等,这里是通过SparkEnv类的伴生对象SparkEnv Object内的Create方法实现的。

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)

3、创建TaskScheduler和DAGScheduler

以下这段代码很重要,它初始化了SparkContex里两个很关键的变量,TaskScheduler和DAGScheduler。

private[spark] var taskScheduler = SparkContext.createTaskScheduler(this, master)
@volatile private[spark] var dagScheduler: DAGScheduler = _
try {
dagScheduler = new DAGScheduler(this)
} catch {
case e: Exception => throw
new SparkException("DAGScheduler cannot be initialized due to %s".format(e.getMessage))
} // start TaskScheduler after taskScheduler sets DAGScheduler reference in DAGScheduler's
// constructor
taskScheduler.start()

首先,TaskScheduler是依据Spark的执行模式进行初始化的,详细代码在SparkContext中的createTaskScheduler方法中。以Standalone模式为例,它会将sc传递给TaskSchedulerImpl,并在返回Scheduler对象之前,创建SparkDeploySchedulerBackend,并将其初始化,最后返回Scheduler对象。

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)
scheduler

创建TaskScheduler对象后,再将TaskScheduler对象传參至DAGScheduler,用来创建DAGScheduler对象,

def this(sc: SparkContext, taskScheduler: TaskScheduler) = {
this(
sc,
taskScheduler,
sc.listenerBus,
sc.env.mapOutputTracker.asInstanceOf[MapOutputTrackerMaster],
sc.env.blockManager.master,
sc.env)
}

之后,再调用其start()方法将其启动,当中包含SchedulerBackend的启动。

override def start() {
backend.start() if (!isLocal && conf.getBoolean("spark.speculation", false)) {
logInfo("Starting speculative execution thread")
import sc.env.actorSystem.dispatcher
sc.env.actorSystem.scheduler.schedule(SPECULATION_INTERVAL milliseconds,
SPECULATION_INTERVAL milliseconds) {
Utils.tryOrExit { checkSpeculatableTasks() }
}
}
}

除此之外,SparkContex还包含一些重要的函数方法,比如

1、runjob

runjob是spark中全部任务提交的入口,诸如rdd中的一些常见操作和变换,都会调用SparkContex的runjob方法,提交任务。

def runJob[T, U: ClassTag](
rdd: RDD[T],
func: (TaskContext, Iterator[T]) => U,
partitions: Seq[Int],
allowLocal: Boolean,
resultHandler: (Int, U) => Unit) {
if (dagScheduler == null) {
throw new SparkException("SparkContext has been shutdown")
}
val callSite = getCallSite
val cleanedFunc = clean(func)
logInfo("Starting job: " + callSite)
val start = System.nanoTime
dagScheduler.runJob(rdd, cleanedFunc, partitions, callSite, allowLocal,
resultHandler, localProperties.get)
logInfo("Job finished: " + callSite + ", took " + (System.nanoTime - start) / 1e9 + " s")
rdd.doCheckpoint()
}

2、textFile

从HDFS路径读取单个数据文件,首先创建HadoopRDD,通过map操作,返回RDD对象。

3、wholeTextFiles

从HDFS某个目录读取多个文件。

4、parallelize

读取本地文件,并转换为RDD。

[Apache Spark源代码阅读]天堂之门——SparkContext解析的更多相关文章

  1. Spark源代码阅读笔记之DiskStore

    Spark源代码阅读笔记之DiskStore BlockManager底层通过BlockStore来对数据进行实际的存储.BlockStore是一个抽象类,有三种实现:DiskStore(磁盘级别的持 ...

  2. Spark修炼之道(高级篇)——Spark源代码阅读:第十二节 Spark SQL 处理流程分析

    作者:周志湖 以下的代码演示了通过Case Class进行表Schema定义的样例: // sc is an existing SparkContext. val sqlContext = new o ...

  3. Spark源代码阅读笔记之MetadataCleaner

    MetadataCleaner执行定时任务周期性的清理元数据(metadata),有6种类型的元数据:MAP_OUTPUT_TRACKER.executor跟踪各个map任务输出的存储位置的数据,依据 ...

  4. Apache Spark源码走读之11 -- sql的解析与执行

    欢迎转载,转载请注明出处,徽沪一郎. 概要 在即将发布的spark 1.0中有一个新增的功能,即对sql的支持,也就是说可以用sql来对数据进行查询,这对于DBA来说无疑是一大福音,因为以前的知识继续 ...

  5. ERROR actor.OneForOneStrategy: org.apache.spark.SparkContext

    今天在用Spark把Kafka的数据往ES写的时候,代码一直报错,错误信息如下: 15/10/20 17:28:56 ERROR actor.OneForOneStrategy: org.apache ...

  6. Apache Spark 2.2.0 中文文档

    Apache Spark 2.2.0 中文文档 - 快速入门 | ApacheCN Geekhoo 关注 2017.09.20 13:55* 字数 2062 阅读 13评论 0喜欢 1 快速入门 使用 ...

  7. Apache Spark源码剖析

    Apache Spark源码剖析(全面系统介绍Spark源码,提供分析源码的实用技巧和合理的阅读顺序,充分了解Spark的设计思想和运行机理) 许鹏 著   ISBN 978-7-121-25420- ...

  8. 《Apache Spark源码剖析》

    Spark Contributor,Databricks工程师连城,华为大数据平台开发部部长陈亮,网易杭州研究院副院长汪源,TalkingData首席数据科学家张夏天联袂力荐1.本书全面.系统地介绍了 ...

  9. Apache Spark 2.2.0 中文文档 - Spark 编程指南 | ApacheCN

    Spark 编程指南 概述 Spark 依赖 初始化 Spark 使用 Shell 弹性分布式数据集 (RDDs) 并行集合 外部 Datasets(数据集) RDD 操作 基础 传递 Functio ...

随机推荐

  1. C#基础总结之Attribute

    Attribute是什么 Attribute的中文姓名 为什么我要拿一段文字来说Attribute的中文姓名呢?答案是:因为这很重要.正所谓“名”不正,则言不顺:另外重构手法中有一种很重要的方法叫重命 ...

  2. HTML5游戏开发进阶指南

    <HTML5游戏开发进阶指南> 基本信息 作者: (印)香卡(Shankar,A.R.)    译者: 谢光磊 出版社:电子工业出版社 ISBN:9787121212260 上架时间:20 ...

  3. Redis深入之数据结构

    Redis主要数据结构 链表 Redis使用的C语言并没有内置这样的数据结构,所以Redis构建了自己的链表实现.列表键的底层实现之中的一个就是链表,一个列表键包括了数量比較多的元素,列表中包括的元素 ...

  4. JS 昵称,手机号,邮箱判断

    <script type="text/javascript"> var leyou = document.getElementById('J-leyou'), _nam ...

  5. margin 还能够被缩回

    <p><strong>话:</strong>的肥沃和收获而被估价的.才干也是土地,只是它生产的不是粮食,而是真理.假设仅仅能滋生瞑想和幻想的话,即使再大的才干也仅仅 ...

  6. CentOS7+Tomcat 生产系统部署

    1 准备OS账户 安全起见,本着最小权限原则,生产系统决不同意使用root账户来执行tomcat.为此,建立新账户tomcat,并设定登录password. useradd tomcat passwd ...

  7. JavaScript 内存

    JavaScript 中对内存的一些了解 在使用JavaScript进行开发的过程中,了解JavaScript内存机制有助于开发人员能够清晰的认识到自己写的代码在执行的过程中发生过什么,也能够提高项目 ...

  8. Java EE (3) -- Java EE 6 Web Services Developer Certified Expert(1z0-897)

    Create an SOAP web service in a servlet container Create a RESTful web service in a servlet containe ...

  9. Google的Guava它Collection升华

    至于Guava这是不是在这里说.一个已被提上一个非常特殊的! 这主要是为了分享Guava对于一些升华处理组.井,不多说了,直接在代码: package com.joyce.guava.bean; /* ...

  10. 【iOS开发-22】navigationBar导航栏,navigationItem建立:获取导航栏中的基本文本和button以及各种跳跃

    (1)navigationBar导航栏可以被看作是self.navigationController一个属性导航控制器,它可以由点直接表示self.navigationController.navig ...