1. 简介

SparkConf类负责管理Spark的所有配置项。在我们使用Spark的过程中,经常需要灵活配置各种参数,来使程序更好、更快地运行,因此也必然要与SparkConf类频繁打交道。了解它的细节不无裨益。

2. SparkConf类的构造方法

下面先来看一看SparkConf类的构造方法。为了读起来清晰明了,可能会在不影响理解的前提下适当删去无关代码、注释,并调整顺序。

class SparkConf(loadDefaults: Boolean) extends Cloneable with Logging with Serializable {import SparkConf._

if (loadDefaults) { loadFromSystemProperties(false) }
def this() = this(true)
// ...}

代码中的import语句是从SparkConf类的伴生对象中导入一些东西,它们主要管理过期的、旧版本兼容的配置项,以及日志输出。Scala中没有Java的静态(static)概念,类的伴生对象中维护的成员和方法就可以视为类的静态成员和静态方法。

SparkConf类有一个主构造方法参数loadDefaults,它指示是否要从Java系统属性(即System.getProperties()取得的属性)加载默认的与Spark相关的配置。

3. Spark配置项的存储

SparkConf内部是采用ConcurrentHashMap来维护所有配置项键值的。

private val settings = new ConcurrentHashMap[String, String]()

这自然是考虑到了并发环境下的线程安全性问题。另外,它的键与值类型都为String,说明所有Spark配置项都以字符串形式存储。

3.1 设置配置项

要设置Spark配置项,有以下三种方法。

(1) 直接用Set类方法设置

这是我们开发过程中最常用的方法。SparkConf中提供了多种多样的Set类方法,最基础的set()方法重载如下。

def set(key: String, value: String): SparkConf = {set(key, value, false) }
private[spark] def set(key: String, value: String, silent: Boolean): SparkConf = {if (key == null) { throw new NullPointerException("null key") }if (value == null) { throw new NullPointerException("null value for " + key) }if (!silent) { logDeprecationWarning(key) } settings.put(key, value) this }

可见配置项的键值都不能为null。并且包括set()在内的所有Set类方法都返回this,所以支持链式调用,这样使用起来比较简洁。

另外,还有一些方法可以快速设置常用配置项,比如上篇代码#0.1中出现过的setMaster()与setAppName()。它们最终也会调用set()方法。

def setMaster(master: String): SparkConf = { set("spark.master", master) }

def setAppName(name: String): SparkConf = { set("spark.app.name", name) }

(2) 通过系统属性加载

如果上述代码#1.1中的loadDefaults参数为true,那么SparkConf会从Java系统属性中加载配置项。如果调用无参的辅助构造方法,即直接new SparkConf()的话,也会将loadDefaults设为true。Java系统属性可以通过System.setProperty()方法在程序中动态设置。

来看代码#1.1中调用的loadFromSystemProperties()方法。

private[spark] def loadFromSystemProperties(silent: Boolean): SparkConf = {for ((key, value) <- Utils.getSystemProperties if key.startsWith("spark.")) {set(key, value, silent) }this }

它使用通用工具类Utils中的方法取得系统属性,过滤出以字符串“spark.”为前缀的键,然后调用set()方法设置键值。由于系统属性相关的参数是一次性初始化的,所以用Set类方法设置的值可以覆盖它们。

(3) 克隆SparkConf

SparkConf类继承了Cloneable特征(trait,类似于Java接口的增强版)并覆写了clone()方法,因此SparkConf是可以(深)克隆的。

override def clone: SparkConf = { val cloned = new SparkConf(false) settings.entrySet().asScala.foreach { e => cloned.set(e.getKey(), e.getValue(), true) } cloned }

虽然ConcurrentHashMap保证线程安全,不会影响SparkConf实例共享,但在高并发的情况下,锁机制可能会带来性能问题。我们就可以克隆SparkConf到多个组件中,以让它们获得相同的配置参数。

3.2 获取配置项

获取配置项只有一个途径,即调用Get类方法。Get类方法同样有很多实现,基础的get()与getOption()如下所示。

def get(key: String): String = { getOption(key).getOrElse(throw new NoSuchElementException(key)) }

def get(key: String, defaultValue: String): String = { getOption(key).getOrElse(defaultValue) }
def getOption(key: String): Option[String] = { Option(settings.get(key)).orElse(getDeprecatedConfig(key, settings)) }

获取配置项时,会同时检查过期配置(getDeprecatedConfig()方法是伴生对象中定义的),并且会使用Scala Option来包装返回的结果,对于有值(Some)和无值(None)的情况可以灵活处理。

另外,Get类方法中有不少涉及数据类型转换和单位转换,如getDouble()、getLong()、getSizeAsMb()、getTimeAsSeconds()等等,都是为了使用方便,不再赘述。

3.3 校验配置项

SparkConf中有一个方法validateSettings(),用来校验配置项。它的源码很长,但是逻辑比较简单,主要是对过期配置项进行警告,以及对非法设置或不兼容的配置项抛出异常。

限于篇幅原因,这里就不贴出该方法的源码了。感兴趣的看官可以自己找找看,里面校验了大量之后一定会用到的配置项。

总结

本文通过SparkConf类的部分源码,简述了SparkConf的构造方法、配置存储,以及设置、获取、校验配置项的方法逻辑。

SparkConf是SparkContext初始化的必备前提。了解了SparkConf,就可以分析复杂得多的SparkContext了。

转自:https://mp.weixin.qq.com/s/8HXWhfl-w-UU-0Zy4YHl2g

Spark源码(1): SparkConf的更多相关文章

  1. Spark源码剖析 - SparkContext的初始化(二)_创建执行环境SparkEnv

    2. 创建执行环境SparkEnv SparkEnv是Spark的执行环境对象,其中包括众多与Executor执行相关的对象.由于在local模式下Driver会创建Executor,local-cl ...

  2. Spark源码分析:多种部署方式之间的区别与联系(转)

    原文链接:Spark源码分析:多种部署方式之间的区别与联系(1) 从官方的文档我们可以知道,Spark的部署方式有很多种:local.Standalone.Mesos.YARN.....不同部署方式的 ...

  3. Spark源码分析之九:内存管理模型

    Spark是现在很流行的一个基于内存的分布式计算框架,既然是基于内存,那么自然而然的,内存的管理就是Spark存储管理的重中之重了.那么,Spark究竟采用什么样的内存管理模型呢?本文就为大家揭开Sp ...

  4. Spark源码分析之八:Task运行(二)

    在<Spark源码分析之七:Task运行(一)>一文中,我们详细叙述了Task运行的整体流程,最终Task被传输到Executor上,启动一个对应的TaskRunner线程,并且在线程池中 ...

  5. Spark源码分析之五:Task调度(一)

    在前四篇博文中,我们分析了Job提交运行总流程的第一阶段Stage划分与提交,它又被细化为三个分阶段: 1.Job的调度模型与运行反馈: 2.Stage划分: 3.Stage提交:对应TaskSet的 ...

  6. spark 源码分析之四 -- TaskScheduler的创建和启动过程

    在 spark 源码分析之二 -- SparkContext 的初始化过程 中,第 14 步 和 16 步分别描述了 TaskScheduler的 初始化 和 启动过程. 话分两头,先说 TaskSc ...

  7. spark源码单步跟踪阅读-从毛片说起

    想当年读大学时,那时毛片还叫毛片,现在有文明的叫法了,叫小电影或者爱情动作片.那时宿舍有位大神,喜欢看各种毛片,当我们纠结于毛片上的马赛克时,大神大手一挥说道:这算啥,阅尽天下毛片,心中自然无码!突然 ...

  8. spark源码分析以及优化

    第一章.spark源码分析之RDD四种依赖关系 一.RDD四种依赖关系 RDD四种依赖关系,分别是 ShuffleDependency.PrunDependency.RangeDependency和O ...

  9. Spark 源码浅读-SparkSubmit

    Spark 源码浅读-任务提交SparkSubmit main方法 main方法主要用于初始化日志,然后接着调用doSubmit方法. override def main(args: Array[St ...

随机推荐

  1. Java基础 static限定符的使用 以及【 static实现的 singleton(单例)设计模式】

    static实现的 singleton(单例)设计模式 /** static实现的 singleton设计模式 , 使得一个类只能够创建一个static对象 */ 模板设计结构: package Co ...

  2. ASP.NET Core 2.0身份和角色管理入门

    见  https://blog.csdn.net/mzl87/article/details/84892916 https://www.codeproject.com/Articles/1235077 ...

  3. 项目:jSon和Ajax登录功能

    组件化网页开发 / 步骤二 · 项目:jSon和Ajax登录功能 要熟练编写封装的$.ajax({........})

  4. AtCoder Beginner Contest 148

    ABC 148 第一次打abc,记录一下 Task Name Time Limit Memory Limit A Round One 2 sec 1024 MB B Strings with the ...

  5. P3355 骑士共存问题【洛谷】(二分图最大独立集变形题) //链接矩阵存图

    展开 题目描述 在一个 n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入 对于给定的 n*n 个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可 ...

  6. vue中把props中的值赋值给data

    vue中把props中的值赋值给data 2018年12月26日 14:37:11 木豆mudou 阅读数 3497   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上 ...

  7. Oracle 物理结构(四) 文件-控制文件

    一.什么是控制文件 控制文件是Oracle数据库中十分重要的文件.Oracle启动时,首先会读取参数文件,读取了参数文件,实例所需要的共享内存和后台进程就可以启动了,这就是数据库实例的nomunt阶段 ...

  8. luoguP4778 Counting swaps

    题目链接 题解 首先,对于每个\(i\)向\(a[i]\)连边. 这样会连出许多独立的环. 可以证明,交换操作不会跨越环. 每个环内的点到最终状态最少交换步数是 \(环的大小-1\) 那么设\(f[i ...

  9. CComboBoxEx添加图像CImageList无法正常显示

    <1>给控件 CComboBox绑定变量 .cpp中 DDX_Control(pDX, IDC_COMBO_PHOTO_IMG, m_ComboBoxPhotoImg); CComboBo ...

  10. java 架构师思维导图

    java 基础 . 理解IO.多线程.集合等基础框架.对JVM原理有一定了解. spring  spring boot  ibatis   structs开源框架了解. 熟悉分布式系统设计和应用. 小 ...