SparkContext源码阅读
SparkContext是spark的入口,通过它来连接集群、创建RDD、广播变量等等。
class SparkContext(config: SparkConf) extends Logging with ExecutorAllocationClient {
private val creationSite: CallSite = Utils.getCallSite()
//如果生命了2个sparkContext,则会使用warn来取代exception.防止退出
private val allowMultipleContexts: Boolean =
config.getBoolean("spark.driver.allowMultipleContexts", false)
..防止两个sparkcontext同时运行
SparkContext.markPartiallyConstructed(this, allowMultipleContexts)
private[spark] var preferredNodeLocationData: Map[String, Set[SplitInfo]] = Map()
val startTime = System.currentTimeMillis()
//当提交任务执行spark-submit时,加载系统环境变量
def this() = this(new SparkConf())
def this(master: String, appName: String, conf: SparkConf) =
this(SparkContext.updatedConf(conf, master, appName))
//preferredNodeLocationData 用于启动查找nodes,启动相应的container
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))
if (preferredNodeLocationData.nonEmpty) {
logWarning("Passing in preferred locations has no effect at all, see SPARK-8949")
}
this.preferredNodeLocationData = preferredNodeLocationData
//构造函数
private[spark] def this(master: String, appName: String) =
this(master, appName, null, Nil, Map(), Map())
private[spark] def this(master: String, appName: String, sparkHome: String) =
this(master, appName, sparkHome, Nil, Map(), Map())
private[spark] def this(master: String, appName: String, sparkHome: String, jars: Seq[String]) =
this(master, appName, sparkHome, jars, Map(), Map())
private[spark] def conf: SparkConf = _conf
//clone Conf,那么在运行时就不能被修改
def getConf: SparkConf = conf.clone()
def jars: Seq[String] = _jars
def files: Seq[String] = _files
def master: String = _conf.get("spark.master")
def appName: String = _conf.get("spark.app.name")
private[spark] def isEventLogEnabled: Boolean = _conf.getBoolean("spark.eventLog.enabled", false)
private[spark] def eventLogDir: Option[URI] = _eventLogDir
private[spark] def eventLogCodec: Option[String] = _eventLogCodec
//创建schedular
val (sched, ts) = SparkContext.createTaskScheduler(this, master)
_schedulerBackend = sched
_taskScheduler = ts
_dagScheduler = new DAGScheduler(this)
_heartbeatReceiver.ask[Boolean](TaskSchedulerIsSet)
//启动taskschedular
_taskScheduler.start()
applicationId = _taskScheduler.applicationId()
_applicationAttemptId = taskScheduler.applicationAttemptId()
_conf.set("spark.app.id", _applicationId)
_env.blockManager.initialize(_applicationId)
//创建一个新的RDD,通过step来增加元素
def range(
start: Long,
end: Long,
step: Long = 1,
numSlices: Int = defaultParallelism): RDD[Long] = withScope {
assertNotStopped()
// when step is 0, range will run infinitely
require(step != 0, "step cannot be 0")
val numElements: BigInt = {
val safeStart = BigInt(start)
val safeEnd = BigInt(end)
if ((safeEnd - safeStart) % step == 0 || safeEnd > safeStart ^ step > 0) {
(safeEnd - safeStart) / step
} else {
(safeEnd - safeStart) / step + 1
}
}
parallelize(0 until numSlices, numSlices).mapPartitionsWithIndex((i, _) => {
val partitionStart = (i * numElements) / numSlices * step + start
val partitionEnd = (((i + 1) * numElements) / numSlices) * step + start
def getSafeMargin(bi: BigInt): Long =
if (bi.isValidLong) {
bi.toLong
} else if (bi > 0) {
Long.MaxValue
} else {
Long.MinValue
}
val safePartitionStart = getSafeMargin(partitionStart)
val safePartitionEnd = getSafeMargin(partitionEnd)
new Iterator[Long] {
private[this] var number: Long = safePartitionStart
private[this] var overflow: Boolean = false
override def hasNext =
if (!overflow) {
if (step > 0) {
number < safePartitionEnd
} else {
number > safePartitionEnd
}
} else false
override def next() = {
val ret = number
number += step
if (number < ret ^ step < 0) {
overflow = true
}
ret
}
}
})
}
//创建一个RDD
def makeRDD[T: ClassTag](
seq: Seq[T],
numSlices: Int = defaultParallelism): RDD[T] = withScope {
parallelize(seq, numSlices)
}
//读取本地、HDFS的文件,返回一个String的字符串
def textFile(
path: String,
minPartitions: Int = defaultMinPartitions): RDD[String] = withScope {
assertNotStopped()
hadoopFile(path, classOf[TextInputFormat], classOf[LongWritable], classOf[Text],
minPartitions).map(pair => pair._2.toString)
}
//加载一个二进制文件,
@Experimental
def binaryRecords(
path: String,
recordLength: Int,
conf: Configuration = hadoopConfiguration): RDD[Array[Byte]] = withScope {
assertNotStopped()
conf.setInt(FixedLengthBinaryInputFormat.RECORD_LENGTH_PROPERTY, recordLength)
val br = newAPIHadoopFile[LongWritable, BytesWritable, FixedLengthBinaryInputFormat](path,
classOf[FixedLengthBinaryInputFormat],
classOf[LongWritable],
classOf[BytesWritable],
conf = conf)
val data = br.map { case (k, v) =>
val bytes = v.getBytes
assert(bytes.length == recordLength, "Byte array does not have correct length")
bytes
}
data
}
//获得一个为HADOOP sequenceFile给定键值对类型的RDD
def sequenceFile[K, V](path: String,
keyClass: Class[K],
valueClass: Class[V],
minPartitions: Int
): RDD[(K, V)] = withScope {
assertNotStopped()
val inputFormatClass = classOf[SequenceFileInputFormat[K, V]]
hadoopFile(path, inputFormatClass, keyClass, valueClass, minPartitions)
}
//1300发送一个广播变量到集群的每个节点
def broadcast[T: ClassTag](value: T): Broadcast[T] = {
assertNotStopped()
if (classOf[RDD[_]].isAssignableFrom(classTag[T].runtimeClass)) {
logWarning("Can not directly broadcast RDDs; instead, call collect() and "
+ "broadcast the result (see SPARK-5063)")
}
val bc = env.broadcastManager.newBroadcast[T](value, isLocal)
val callSite = getCallSite
logInfo("Created broadcast " + bc.id + " from " + callSite.shortForm)
cleaner.foreach(_.registerBroadcastForCleanup(bc))
bc
}
SparkContext源码阅读的更多相关文章
- SparkConf加载与SparkContext创建(源码阅读一)
即日起开始spark源码阅读之旅,这个过程是相当痛苦的,也许有大量的看不懂,但是每天一个方法,一点点看,相信总归会有极大地提高的.那么下面开始: 创建sparkConf对象,那么究竟它干了什么了类,从 ...
- Spark源码阅读之存储体系--存储体系概述与shuffle服务
一.概述 根据<深入理解Spark:核心思想与源码分析>一书,结合最新的spark源代码master分支进行源码阅读,对新版本的代码加上自己的一些理解,如有错误,希望指出. 1.块管理器B ...
- 【原】FMDB源码阅读(三)
[原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...
- 【原】FMDB源码阅读(二)
[原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...
- 【原】FMDB源码阅读(一)
[原]FMDB源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 说实话,之前的SDWebImage和AFNetworking这两个组件我还是使用过的,但是对于 ...
- 【原】AFNetworking源码阅读(六)
[原]AFNetworking源码阅读(六) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这一篇的想讲的,一个就是分析一下AFSecurityPolicy文件,看看AF ...
- 【原】AFNetworking源码阅读(五)
[原]AFNetworking源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中提及到了Multipart Request的构建方法- [AFHTTP ...
- 【原】AFNetworking源码阅读(四)
[原]AFNetworking源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇还遗留了很多问题,包括AFURLSessionManagerTaskDe ...
- 【原】AFNetworking源码阅读(三)
[原]AFNetworking源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇的话,主要是讲了如何通过构建一个request来生成一个data tas ...
随机推荐
- 三层交换单臂路由vlan间通信综合实验之降龙要点[转]
单臂路由三层交换机提供vlan间的通信之菜鸟之降龙详解要点: 图示 PC:左到右依次设置IP172.16.10.1, 20.1, 30.1, 40,1 ,50,1 /24 网关10.2 ...
- iOS开发UI篇—UITableview控件使用小结
iOS开发UI篇—UITableview控件使用小结 一.UITableview的使用步骤 UITableview的使用就只有简单的三个步骤: 1.告诉一共有多少组数据 方法:- (NSInteger ...
- Makefile三个有用变量$@,$^,$<
$@:目标文件 $^:所有的依赖文件 $<:第一个依赖文件 使用上面三个变量就可以简化我们的Makefile文件: #简化后的Makefile main : main.o log.o test_ ...
- 集合ArrayList
/*集合ArrayList * 例如: * 1.创建:ArrayList<Egg> myList = new ArrayList<Egg>(); * Egg类型的集合 ...
- iOS UITableViewCell 中 调整imageView 的图片大小
在我的项目中,很多地方都希望将UITableViewCell 中的imageView 能根据自己图片的大小来进行展示,而就为了解决这个问题又觉得重写UITableViewCell 很不值得. 如下: ...
- 安装生物信息学软件-Samtools
装完Bowtie2,官方文档给出的栗子说可以玩一玩samtools,所以我入个坑 参考这篇http://m.010lm.com/roll/2016/0620/2343389.html Step 1: ...
- 数据库连接JDBC和数据库连接池C3P0自定义的java封装类
数据库连接JDBC和数据库连接池C3P0自定义的java封装类 使用以下的包装类都需要自己有JDBC的驱动jar包: 如 mysql-connector-java-5.1.26-bin.jar(5.1 ...
- 在Mac环境下跑汇编
今天汇编作业做到第七章,就想在Mac下跑自己的asm程序,看到了一个很好的教程: http://www.raywenderlich.com/37181/ios-assembly-tutorial 虽然 ...
- JS中 obj.style.left 与 obj.offsetLeft 的区别
1.obj.style.left 取得是字符串:28px; 而 obj.offsetLeft取得的值为数字 28: 2.obj.style.left 需要事先将left值写在HTML中,不能致谢在CS ...
- Unity3D实现摄像机视野的拉远拉近和跟随主角旋转效果
在Unity官网教程SurvivalShooter(恶魔射手)中,只处理了主角跟随鼠标旋转,摄像机视野并没有旋转或通过滚轮实现视野的拉远拉近,一下是我的实现方法. 在教程中,主角的移动是通过 ...