Spark源码-SparkConf
这个类的目的是配置用户运行时的一些配置,因为是伴生类和伴生对象,所以分为2部分讲解。
SparkConf Class
这个类有几个属性:
- settings = new ConcurrentHashMap[String, String]() 一个线程安全的hashMap 用来保存配置key-value
- private lazy val reader: ConfigReader 一个configReader读取器
这个里面涉及到了SparkConfigProvider这个类的说明参见文章下面 - loadDefaults: Boolean 用来flag是否从SystemProperties加载properties
这个类的构造方法:
- def this() = this(true) 转移到第2个构造方法去,默认SystemProperties加载properties
- class SparkConf(loadDefaults: Boolean) 执行这个构造方法时,会执行这个类的 loadFromSystemProperties(false) 方法,会把system properties 以 spark.* 开头的值遍历加入到 这个类的settings属性;如果传入参数为false的话,会加载已经打印提示用户可能这些配置已经被DeprecationWarning和可能已经被某些参数替换了(被压制的 deprecatedConfigs 列表是SparkConf object 的一个属性,configsWithAlternatives 也一样)
最新这个key-value config 被put 到 这个类的settings属性中了
SparkConf object
ConfigProvider
ConfigProvider是一个trait,目的在于提供一个统一的get configuration values 的接口。
//返回的是一个 Option[String]类型的值
def get(key: String): Option[String]
一共有4个实现类:
- EnvProvider
- SystemProvider
- MapProvider
- SparkConfigProvider
EnvProvider
private[spark] class EnvProvider extends ConfigProvider {
//sys.env 返回的是不会被修改的当前系统环境
override def get(key: String): Option[String] = sys.env.get(key)
}
SystemProvider
private[spark] class SystemProvider extends ConfigProvider {
//sys.props返回的是系统的属性,以下内容一定是存在的
//java.version Java version number
//java.vendor Java vendor specific string
//java.vendor.url Java vendor URL
//java.home Java installation directory
//java.class.version Java class version number
//java.class.path Java classpath
//os.name Operating System Name
//os.arch Operating System Architecture
//os.version Operating System Version
//file.separator File separator ("/" on Unix)
//path.separator Path separator (":" on Unix)
//line.separator Line separator ("\n" on Unix)
//user.name User account name
//user.home User home directory
//user.dir User's current working directory
override def get(key: String): Option[String] = sys.props.get(key)
}
MapProvider
import java.util.{Map => JMap}
//可以看到它的构造方法中需要一个java的map,在获取java map 的内容时候,只是用scala 的 option 做了一层包装。
private[spark] class MapProvider(conf: JMap[String, String]) extends ConfigProvider {
override def get(key: String): Option[String] = Option(conf.get(key))
}
SparkConfigProvider
import java.util.{Map => JMap}
//可以看到它的构造方法中也需要一个java的map,在获取java map 的内容时候,只允许获取以 spark. 开头的key的值,否则返回None。
//当获取以 spark. 开头的key的值,且在这个java map 中没有值的时候,将会继续从SparkConf.getDeprecatedConfig (已经过时的配置)中获取 值。
private[spark] class SparkConfigProvider(conf: JMap[String, String]) extends ConfigProvider {
override def get(key: String): Option[String] = {
if (key.startsWith("spark.")) {
Option(conf.get(key)).orElse(SparkConf.getDeprecatedConfig(key, conf))
} else {
None
}
}
}
ConfigReader class object
ConfigReader 这个类用来读取config entries。
ConfigReader object
这个伴生对象里面只是有一个模式常量:
private val REF_RE = "\\$\\{(?:(\\w+?):)?(\\S+?)\\}".r
ConfigReader class
属性:
- bindings = new HashMap[String, ConfigProvider]() 保存 env,system 等的ConfigProvider
- conf 构造方法传进来的 ConfigProvider
构造方法:
//这里的ConfigProvider 是一个trait,一共有4个实现类
//这个构造方法 初始化 自己属性的conf:ConfigProvider
class ConfigReader(conf: ConfigProvider){
//属性bindings 缓存 构造时的 null -> ConfigProvider,env -> EnvProvider,system -> SystemProvider
//避免不同环境的conf 覆盖
bind(null, conf)
bindEnv(new EnvProvider())
bindSystem(new SystemProvider())
}
//这个构造方法可以传进来一个java map,在内部会转化为ConfigProvider trait的一个实现类 MapProvider,再转移到上面的构造方法中去了
def this(conf: JMap[String, String]) = this(new MapProvider(conf))
这个类的substitute方法是一个比较复杂的,目的在于如果 在 属性conf 中通过key查到的值是特殊的,比如${env.java} 这种形式的 值,这个方法则会自己解析这个value,继续从EnvProvider、SystemProvider获取真实的值。