Spark源码-StaticSQLConf (scala)

StaticSQLConf源码阅读

StaticSQLConf Object

StaticSQLConf 的作用就是设置一些不可变的 spark configuration,而且是跨session的,这些 spark configuration可以通过SparkSession.conf查看,但是不能修改。
里面已经预置了一些配置,(ConfigEntry是一个抽象类):
1.WAREHOUSE_PATH:ConfigEntry
在生成warehouse_path 的时候,会尝试解析网络uri,当失败的时候,会生成此目录下路径的file uri
2.CATALOG_IMPLEMENTATION:ConfigEntry
3.GLOBAL_TEMP_DATABASE:ConfigEntry
4.SCHEMA_STRING_LENGTH_THRESHOLD:ConfigEntry
5.FILESOURCE_TABLE_RELATION_CACHE_SIZE:ConfigEntry
6.CODEGEN_CACHE_MAX_ENTRIES:ConfigEntry
7.CODEGEN_COMMENTS:ConfigEntry
8.DEBUG_MODE:ConfigEntry
9.HIVE_THRIFT_SERVER_SINGLESESSION:ConfigEntry
10.SPARK_SESSION_EXTENSIONS:ConfigEntry
11.QUERY_EXECUTION_LISTENERS:ConfigEntry
12.STREAMING_QUERY_LISTENERS:ConfigEntry
13.UI_RETAINED_EXECUTIONS:ConfigEntry
以上的配置都是通过SQLConf Object的buildStaticConf方法产生的ConfigEntry;SQLConf Object还有一个buildConf方法,这2个方法不同的是传入的回调函数的不同而已,往下浏览SQLConf Object

SQLConf Object&class

这个文件定义了 Spark SQL的configuration options ;
这个对象里面有2个属性:
1.sqlConfEntries = java.util.Collections.synchronizedMap(
new java.util.HashMapString, ConfigEntry[_]) 存放已经生成的ConfigEntry,用以检测是否重复覆盖,重复的话则会抛出异常
2.staticConfKeys: java.util.Set[String] =
java.util.Collections.synchronizedSet(new java.util.HashSetString)存放已经生成的ConfigEntry的key

方法解读:

// 传入回调函数生成ConfigBuilder,q1何时调用回调函数(在 TypedConfigBuilder 的 create* 的方法中的_onCreate foreach 中)
def buildConf(key: String): ConfigBuilder = ConfigBuilder(key).onCreate(register)

// 传入回调函数生成ConfigBuilder
def buildStaticConf(key: String): ConfigBuilder = {
    ConfigBuilder(key).onCreate { entry =>
      staticConfKeys.add(entry.key)
      SQLConf.register(entry)
    }
  }

ConfigBuilder case class

ConfigBuilder是一个case class,这个类的主要作用是用来产生下面的TypedConfigBuilder 这个类。

ConfigBuilder有4个属性:
1.var _public = true
2.var _doc = “” 这个表示注释文档
3.var onCreate: Option[ConfigEntry[] => Unit] = None 存放ConfigEntry的实例对象 到 null 的函数转化,在TypedConfigBuilder中的createWithDefault、createWithDefaultFunction、createWithDefaultString 方法中 有一个 parent.onCreate.foreach((entry)) 的 语句,这个parent就是在实例化TypedConfigBuilder的时候传进来的ConfigBuilder的实例,即此时会执行 _onCreate 里面的函数,而这个函数是SQLConf的buildStaticConf方法中的匿名函数,这个匿名函数的主要 是把这个entry 注册到 SQLConf有HashMap类型的sqlConfEntries和Set类型的staticConfKeys 中去。
4.var _alternatives = List.empty[String]

ConfigBuilder有13个方法:

//1
def internal(): ConfigBuilder = {
	// 改变 _public 的boolean值
    _public = false
    this
  }

//2
def doc(s: String): ConfigBuilder = {
	// 赋予 _doc 的值
    _doc = s
    this
  }

//3
def onCreate(callback: ConfigEntry[_] => Unit): ConfigBuilder = {
	// _onCreate 赋予 回调函数
    _onCreate = Option(callback)
    this
  }

//4
def withAlternative(key: String): ConfigBuilder = {
    _alternatives = _alternatives :+ key
    this
  }

//5
def intConf: TypedConfigBuilder[Int] = {
	//这个使用的是 TypedConfigBuilder的2个参数的构造方法,converter 就是这个toNumber.. 函数,
	//stringConverter就是这个构造方法写死的函数
    new TypedConfigBuilder(this, toNumber(_, _.toInt, key, "int"))
  }
def longConf: TypedConfigBuilder[Long] = {
    new TypedConfigBuilder(this, toNumber(_, _.toLong, key, "long"))
  }

  def doubleConf: TypedConfigBuilder[Double] = {
    new TypedConfigBuilder(this, toNumber(_, _.toDouble, key, "double"))
  }

  def booleanConf: TypedConfigBuilder[Boolean] = {
    new TypedConfigBuilder(this, toBoolean(_, key))
  }

  def stringConf: TypedConfigBuilder[String] = {
    new TypedConfigBuilder(this, v => v)
  }

  def timeConf(unit: TimeUnit): TypedConfigBuilder[Long] = {
    new TypedConfigBuilder(this, timeFromString(_, unit), timeToString(_, unit))
  }

  def bytesConf(unit: ByteUnit): TypedConfigBuilder[Long] = {
    new TypedConfigBuilder(this, byteFromString(_, unit), byteToString(_, unit))
  }

  def fallbackConf[T](fallback: ConfigEntry[T]): ConfigEntry[T] = {
    val entry = new FallbackConfigEntry(key, _alternatives, _doc, _public, fallback)
    _onCreate.foreach(_(entry))
    entry
  }

  def regexConf: TypedConfigBuilder[Regex] = {
    new TypedConfigBuilder(this, regexFromString(_, this.key), _.toString)
  }

TypedConfigBuilder class

这个类的目的是进行统一的类型转化,包括类型和范围的校验(通过函数的嵌套调用),通过其自己的方法(createWithDefault、createWithDefaultFunction、createWithDefaultString)转化为所需的ConfigEntry的子类。
其有3个属性:
1.parent: ConfigBuilder,
2.converter: String => T, 这个是函数类型的属性
3.stringConverter: T => String, 转String类型的函数属性

2个构造方法,

class TypedConfigBuilder[T](
  val parent: ConfigBuilder,
  val converter: String => T,
  val stringConverter: T => String){
  
	def this(parent: ConfigBuilder, converter: String => T) = {
    	this(parent, converter, Option(_).map(_.toString).orNull)
  }

	//注意这个方法,是对函数进行递归调用,形成函数作用链,
	//最主要的作用在于用户自定义的参数检查
	def transform(fn: T => T): TypedConfigBuilder[T] = {
    new TypedConfigBuilder(parent, s => fn(converter(s)), stringConverter)
  	}

	// 注意内部调用了 transform 函数
	def checkValue(validator: T => Boolean, errorMsg: String): TypedConfigBuilder[T] = {
	    transform { v =>
	      if (!validator(v)) throw new IllegalArgumentException(errorMsg)
	      v
	    }
	 }
	 
	 // 注意内部调用了 transform 函数
	 def checkValues(validValues: Set[T]): TypedConfigBuilder[T] = {
    	transform { v =>
     	 if (!validValues.contains(v)) {
        	throw new IllegalArgumentException(
          		s"The value of ${parent.key} should be one of ${validValues.mkString(", ")}, but was $v")
      		}
      		v
   	 	}
  	  }
  
  //这个方法是使用频率最高的,当传进来的值是String类型的时候,走的是 if 这个分支,程序跳转到createWithDefaultString这个函数去了
  def createWithDefault(default: T): ConfigEntry[T] = {
    // Treat "String" as a special case, so that both createWithDefault and createWithDefaultString
    // behave the same w.r.t. variable expansion of default values.
    if (default.isInstanceOf[String]) {
      createWithDefaultString(default.asInstanceOf[String])
    } else {
      val transformedDefault = converter(stringConverter(default))
      val entry = new ConfigEntryWithDefault[T](parent.key, parent._alternatives,
        transformedDefault, converter, stringConverter, parent._doc, parent._public)
      parent._onCreate.foreach(_(entry))
      entry
    }
  }

	//这里的parent是 ConfigBuilder
	def createWithDefaultString(default: String): ConfigEntry[T] = {
    val entry = new ConfigEntryWithDefaultString[T](parent.key, parent._alternatives, default,
      converter, stringConverter, parent._doc, parent._public)
     // 调用 注册的回调函数,
     //这个函数是**SQLConf**的buildStaticConf方法中的匿名函数,
     //这个匿名函数的主要 是把这个entry 注册到 **SQLConf**有HashMap类型的
     //sqlConfEntries和Set类型的staticConfKeys 中去。
    parent._onCreate.foreach(_(entry))
    entry
  }
}

ConfigEntry abstract class

ConfigEntry 是一个抽象类,有
1.key:String
2.alternatives: List[String]
3.valueConverter: String => T 注意这个是函数类型
4.stringConverter: T => String 注意这个是函数类型
5.doc: String,isPublic: Boolean
这5个属性;
1.ConfigEntryWithDefault 默认值Entry
2.ConfigEntryWithDefaultFunction 默认函数Entry
3.ConfigEntryWithDefaultString 默认String类型值Entry
4.OptionalConfigEntry
5.FallbackConfigEntry
5 个非抽象子类

并且有伴生对象object ConfigEntry,这个伴生对象的主要作用在于,其内部有一个ConcurrentHashMap[String, ConfigEntry[]],用来缓存ConfigEntry,用ConfigEntry.key 做键,用ConfigEntry对象做值;所以里面有 ConfigEntry 的注册和find 方法(def registerEntry(entry: ConfigEntry[]): Unit,def findEntry(key: String): ConfigEntry[_])

看这个类的构造方法里面会通过其伴生对象来注册自己的实例。

这个类主要通过TypedConfigBuilder 类的方法 配合生成对象

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值