------------恢复内容开始------------

1.主要功能:SparkConf是Spark的配置类,配置spark的application的应用程序,使用(key,value)来进行存储配置信息。

2.主要形式:val conf=new SparkConf(),读取任何spark.*的配置,包括开发人员所设置的配置,因为SparkConf中含有辅助构造器:def this()=this(true),此辅助构造器中布尔值为true说明读取外部配置信息。在配置单元里可以设置def this()=this(false),跳过外在配置信息。

3.Spark配置:

  Spark中的每一个组件都直接或者间接的使用SparkConf所存储的配置属性,这些属性都存储在数据结构ConcurrentHashMap中即

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

  参数配置的优先级为SparkConf > spark-submit和spark-shell命令的参数指定 > 配置文件spark-defaults.conf。

4.如何获取SparkConf配置:

  (1)来源于系统参数(即System.getproperties获取的属性)中以Spark.作为前缀的那部分属性

  (2)使用SparkConf的API进行设置

  (3)从其它SparkConf中克隆

(1)系统属性中配置

  在SparkConf中有一个Boolean类型属性loadDefaults,当loadDefaults为true时,将从系统属性中加载Spark配置,代码如下:

/** Create a SparkConf that loads defaults from system properties and the classpath */
def this() = this(true) //构造方法 if (loadDefaults) {
loadFromSystemProperties(false)
} private[spark] def loadFromSystemProperties(silent: Boolean): SparkConf = {
// Load any spark.* system properties 加载以spark. 开头的系统属性
for ((key, value) <- Utils.getSystemProperties if key.startsWith("spark.")) {
set(key, value, silent)
}
this
}

loadFromSystemProperties

  上述代码调用了Utils工具类的getSystemProperties方法,其作用为获取系统的键值对属性,loadFromSystemProperties获取到系统属性后,使用scala守卫过滤出以"spark."字符串为前缀的Key和value并且调用set方法,最终设置到settings中

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
}

配置属性存储到settings中

(2)使用SparkConf配置的API

  给SparkConf添加配置的一种常见方式是使用SparkConf提供的API,其中这些API最终实际调用了set的重载方法如:

重载的set方法

/** Set a configuration variable. */
def set(key: String, value: String): SparkConf = {
set(key, value, false)
}

  Sparkconf的setMaster,setAppName,setJars,setExecutorEnv,setSparkHome,setAll等方法都是通过上述的set方法完成Spark配置的,如setMaster和setAppName

/**
* The master URL to connect to, such as "local" to run locally with one thread, "local[4]" to
* run locally with 4 cores, or "spark://master:7077" to run on a Spark standalone cluster.
*/
def setMaster(master: String): SparkConf = {
set("spark.master", master)
} /** Set a name for your application. Shown in the Spark web UI. */
def setAppName(name: String): SparkConf = {
set("spark.app.name", name)
}

添加配置

(3)克隆SparkConf配置

  在某些情况下,同一个SparkConf实例中的配置信息需要被多个组件公用,而我们往往会想到的方法是将SparkConf实例定义为全局变量或者通过参数传递给其他组件,但是这样会引入并发问题,虽然settings数据结构为ConcurrentHashMap是线程安全的,而且ConcurrentHashMap也被证明是高并发下性能表现不错的数据结构,但是存在并发,就一定有性能的损失问题,也可以创建一个SparkConf实例b,并将a中的配置信息全部拷贝到b中,这样会浪费内存,导致代码散落在程序的各个部分。

  SparkConf继承了Cloneable物质并实现了clone方法,可以通过Cloneable物质提高代码的可利用性

Cloneable物质

class SparkConf(loadDefaults: Boolean) extends Cloneable with Logging {
def this() = this(true) /** Copy this object */
override def clone: SparkConf = {
val cloned = new SparkConf(false)
settings.entrySet().asScala.foreach { e =>
cloned.set(e.getKey(), e.getValue(), true)
}
cloned
}
}

5.SparkConf中的优化措施:

(1)SparkConf在spark1.3版本时,spark.yarn.applicationMaster.waitTries是SparkContext初始化失败最大次数,现如今配置成spark.yarn.am.waitTime,重试等待时间,默认为10s,依次递增为20s,30s

waitTries变成waitTime

"spark.yarn.am.waitTime" -> Seq(
AlternateConfig("spark.yarn.applicationMaster.waitTries", "1.3",
// Translate old value to a duration, with 10s wait time per try.
translation = s => s"${s.toLong * 10}s"))

(2)spark.reducer.maxSizeInFlight,默认为48M,此参数用于设置shuffle过程中每个reduce任务需要一个缓冲区来接受map任务输出的结果,而这个缓冲区决定了每次能够拉取多少数据。调优建议:如果作业可用的内存资源较为充足的情况下,可以适当增加这个参数的大小,如设置成96M,从而减少拉取数据的次数,也可以减少网络传输的次数。

 "spark.reducer.maxSizeInFlight" -> Seq(
AlternateConfig("spark.reducer.maxMbInFlight", "1.4"))

spark.reducer.maxSizeInFlight

(3)spark.kryoserializer.buffer

  在Spark的架构中,在网络中传递的或者缓存在内存、硬盘中的对象需要进行序列化操作,序列化的作用主要是利用时间换空间,主要应用于:分发给Executor上的Task,需要缓存的RDD(前提是使用序列化方式缓存的),广播变量,Shuffle过程中的数据缓存,算子函数中使用到的外部变量。大大减少了数据在内存、硬盘中占用的空间,减少了网络数据传输的开销,并且可以精确的推测内存使用情况,降低GC频率。但是把数据序列化为字节数组、把字节数组反序列化为对象的操作,是会消耗CPU、延长作业时间的,从而降低了Spark的性能。使用kryo序列化三步走策略:

  第一步:设置序列化使用的库:conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer");  //使用Kryo序列化库

  第二步:在该库中注册用户定义的类型:conf.set("spark.kryo.registrator", toKryoRegistrator.class.getName());       //在Kryo序列化库中注册自定义的类集合

  第三步:在自定义类中实现KryoRegistrator接口的registerClasses方法

      public static class toKryoRegistrator implements KryoRegistrator {
        public void registerClasses(Kryo kryo) {
          kryo.register(tmp1.class, new FieldSerializer(kryo, tmp1.class)); //在Kryo序列化库中注册自定义的类
          kryo.register(tmp2.class, new FieldSerializer(kryo, tmp2.class)); //在Kryo序列化库中注册自定义的类
        }
      }

(4)spark.shuffle.file.buffer和spark.shuffle.consolidateFiles

  spark中shuffle输出的ShuffleMapTask为每个ResultTask创建对应的Bucket,ShuffleMapTask产生的结果会根据设置partitioner的到对应的BucketId,然后填充到相应的Bucket中。每个ShuffleMapTask的输出结果可能包含所有ResultTask需要的数据,所以每个ShuffleMapTask创建的Bucket的数目和ResultTask的数目是相当的。

  ShuffleMapTask创建的Bucket对应磁盘上的一个文件,用于存储结果,此文件被称为BlockFile。通过 spark.shuffle.file.buffer.kb属性配置的缓冲区就是用来创建BufferedOutputStream输出流的,如果配置文件中设置了spark.shuffle.consolidateFiles属性为true,则ShuffleMapTask所产生的Bucket就不一定单独对应一个文件了,而是对应文件的一部分,这样做会大量减少产生的BlockFile文件数量。

------------恢复内容结束------------

1.主要功能:SparkConf是Spark的配置类,配置spark的application的应用程序,使用(key,value)来进行存储配置信息。

2.主要形式:val conf=new SparkConf(),读取任何spark.*的配置,包括开发人员所设置的配置,因为SparkConf中含有辅助构造器:def this()=this(true),此辅助构造器中布尔值为true说明读取外部配置信息。在配置单元里可以设置def this()=this(false),跳过外在配置信息。

3.Spark配置:

  Spark中的每一个组件都直接或者间接的使用SparkConf所存储的配置属性,这些属性都存储在数据结构ConcurrentHashMap中即

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

4.如何获取SparkConf配置:

  (1)来源于系统参数(即System.getproperties获取的属性)中以Spark.作为前缀的那部分属性

  (2)使用SparkConf的API进行设置

  (3)从其它SparkConf中克隆

(1)系统属性中配置

  在SparkConf中有一个Boolean类型属性loadDefaults,当loadDefaults为true时,将从系统属性中加载Spark配置,代码如下:

/** Create a SparkConf that loads defaults from system properties and the classpath */
def this() = this(true) //构造方法 if (loadDefaults) {
loadFromSystemProperties(false)
} private[spark] def loadFromSystemProperties(silent: Boolean): SparkConf = {
// Load any spark.* system properties 加载以spark. 开头的系统属性
for ((key, value) <- Utils.getSystemProperties if key.startsWith("spark.")) {
set(key, value, silent)
}
this
}

loadFromSystemProperties

  上述代码调用了Utils工具类的getSystemProperties方法,其作用为获取系统的键值对属性,loadFromSystemProperties获取到系统属性后,使用scala守卫过滤出以"spark."字符串为前缀的Key和value并且调用set方法,最终设置到settings中

/** Create a SparkConf that loads defaults from system properties and the classpath */
def this() = this(true) //构造方法 if (loadDefaults) {
loadFromSystemProperties(false)
} private[spark] def loadFromSystemProperties(silent: Boolean): SparkConf = {
// Load any spark.* system properties 加载以spark. 开头的系统属性
for ((key, value) <- Utils.getSystemProperties if key.startsWith("spark.")) {
set(key, value, silent)
}
this
}

(2)使用SparkConf配置的API

  给SparkConf添加配置的一种常见方式是使用SparkConf提供的API,其中这些API最终实际调用了set的重载方法如:

重载的set方法

/** Set a configuration variable. */
def set(key: String, value: String): SparkConf = {
set(key, value, false)
}

  Sparkconf的setMaster,setAppName,setJars,setExecutorEnv,setSparkHome,setAll等方法都是通过上述的set方法完成Spark配置的,如setMaster和setAppName

/**
* The master URL to connect to, such as "local" to run locally with one thread, "local[4]" to
* run locally with 4 cores, or "spark://master:7077" to run on a Spark standalone cluster.
*/
def setMaster(master: String): SparkConf = {
set("spark.master", master)
} /** Set a name for your application. Shown in the Spark web UI. */
def setAppName(name: String): SparkConf = {
set("spark.app.name", name)
}

添加配置

(3)克隆SparkConf配置

  在某些情况下,同一个SparkConf实例中的配置信息需要被多个组件公用,而我们往往会想到的方法是将SparkConf实例定义为全局变量或者通过参数传递给其他组件,但是这样会引入并发问题,虽然settings数据结构为ConcurrentHashMap是线程安全的,而且ConcurrentHashMap也被证明是高并发下性能表现不错的数据结构,但是存在并发,就一定有性能的损失问题,也可以创建一个SparkConf实例b,并将a中的配置信息全部拷贝到b中,这样会浪费内存,导致代码散落在程序的各个部分。

  SparkConf继承了Cloneable物质并实现了clone方法,可以通过Cloneable物质提高代码的可利用性

Cloneable物质

class SparkConf(loadDefaults: Boolean) extends Cloneable with Logging {
def this() = this(true) /** Copy this object */
override def clone: SparkConf = {
val cloned = new SparkConf(false)
settings.entrySet().asScala.foreach { e =>
cloned.set(e.getKey(), e.getValue(), true)
}
cloned
}
}

5.SparkConf中的优化措施:

(1)SparkConf在spark1.3版本时,spark.yarn.applicationMaster.waitTries是SparkContext初始化失败最大次数,现如今配置成spark.yarn.am.waitTime,重试等待时间,默认为10s,依次递增为20s,30s

waitTries变成waitTime

"spark.yarn.am.waitTime" -> Seq(
AlternateConfig("spark.yarn.applicationMaster.waitTries", "1.3",
// Translate old value to a duration, with 10s wait time per try.
translation = s => s"${s.toLong * 10}s"))

(2)spark.reducer.maxSizeInFlight,默认为48M,此参数用于设置shuffle过程中每个reduce任务需要一个缓冲区来接受map任务输出的结果,而这个缓冲区决定了每次能够拉取多少数据。调优建议:如果作业可用的内存资源较为充足的情况下,可以适当增加这个参数的大小,如设置成96M,从而减少拉取数据的次数,也可以减少网络传输的次数。

spark.reducer.maxSizeInFlight

(3)spark.kryoserializer.buffer

  在Spark的架构中,在网络中传递的或者缓存在内存、硬盘中的对象需要进行序列化操作,序列化的作用主要是利用时间换空间,主要应用于:分发给Executor上的Task,需要缓存的RDD(前提是使用序列化方式缓存的),广播变量,Shuffle过程中的数据缓存,算子函数中使用到的外部变量。大大减少了数据在内存、硬盘中占用的空间,减少了网络数据传输的开销,并且可以精确的推测内存使用情况,降低GC频率。但是把数据序列化为字节数组、把字节数组反序列化为对象的操作,是会消耗CPU、延长作业时间的,从而降低了Spark的性能。使用kryo序列化三步走策略:

  第一步:设置序列化使用的库:conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer");  //使用Kryo序列化库

  第二步:在该库中注册用户定义的类型:conf.set("spark.kryo.registrator", toKryoRegistrator.class.getName());       //在Kryo序列化库中注册自定义的类集合

  第三步:在自定义类中实现KryoRegistrator接口的registerClasses方法

      public static class toKryoRegistrator implements KryoRegistrator {
        public void registerClasses(Kryo kryo) {
          kryo.register(tmp1.class, new FieldSerializer(kryo, tmp1.class)); //在Kryo序列化库中注册自定义的类
          kryo.register(tmp2.class, new FieldSerializer(kryo, tmp2.class)); //在Kryo序列化库中注册自定义的类
        }
      }

(4)spark.shuffle.file.buffer和spark.shuffle.consolidateFiles

  spark中shuffle输出的ShuffleMapTask为每个ResultTask创建对应的Bucket,ShuffleMapTask产生的结果会根据设置partitioner的到对应的BucketId,然后填充到相应的Bucket中。每个ShuffleMapTask的输出结果可能包含所有ResultTask需要的数据,所以每个ShuffleMapTask创建的Bucket的数目和ResultTask的数目是相当的。

  ShuffleMapTask创建的Bucket对应磁盘上的一个文件,用于存储结果,此文件被称为BlockFile。通过 spark.shuffle.file.buffer.kb属性配置的缓冲区就是用来创建BufferedOutputStream输出流的,如果配置文件中设置了spark.shuffle.consolidateFiles属性为true,则ShuffleMapTask所产生的Bucket就不一定单独对应一个文件了,而是对应文件的一部分,这样做会大量减少产生的BlockFile文件数量。

SparkConf源码解读的更多相关文章

  1. 15、Spark Streaming源码解读之No Receivers彻底思考

    在前几期文章里讲了带Receiver的Spark Streaming 应用的相关源码解读,但是现在开发Spark Streaming的应用越来越多的采用No Receivers(Direct Appr ...

  2. Spark Streaming源码解读之流数据不断接收和全生命周期彻底研究和思考

    本节的主要内容: 一.数据接受架构和设计模式 二.接受数据的源码解读 Spark Streaming不断持续的接收数据,具有Receiver的Spark 应用程序的考虑. Receiver和Drive ...

  3. SDWebImage源码解读之SDWebImageDownloaderOperation

    第七篇 前言 本篇文章主要讲解下载操作的相关知识,SDWebImageDownloaderOperation的主要任务是把一张图片从服务器下载到内存中.下载数据并不难,如何对下载这一系列的任务进行设计 ...

  4. SDWebImage源码解读 之 NSData+ImageContentType

    第一篇 前言 从今天开始,我将开启一段源码解读的旅途了.在这里先暂时不透露具体解读的源码到底是哪些?因为也可能随着解读的进行会更改计划.但能够肯定的是,这一系列之中肯定会有Swift版本的代码. 说说 ...

  5. SDWebImage源码解读 之 UIImage+GIF

    第二篇 前言 本篇是和GIF相关的一个UIImage的分类.主要提供了三个方法: + (UIImage *)sd_animatedGIFNamed:(NSString *)name ----- 根据名 ...

  6. SDWebImage源码解读 之 SDWebImageCompat

    第三篇 前言 本篇主要解读SDWebImage的配置文件.正如compat的定义,该配置文件主要是兼容Apple的其他设备.也许我们真实的开发平台只有一个,但考虑各个平台的兼容性,对于框架有着很重要的 ...

  7. SDWebImage源码解读_之SDWebImageDecoder

    第四篇 前言 首先,我们要弄明白一个问题? 为什么要对UIImage进行解码呢?难道不能直接使用吗? 其实不解码也是可以使用的,假如说我们通过imageNamed:来加载image,系统默认会在主线程 ...

  8. SDWebImage源码解读之SDWebImageCache(上)

    第五篇 前言 本篇主要讲解图片缓存类的知识,虽然只涉及了图片方面的缓存的设计,但思想同样适用于别的方面的设计.在架构上来说,缓存算是存储设计的一部分.我们把各种不同的存储内容按照功能进行切割后,图片缓 ...

  9. SDWebImage源码解读之SDWebImageCache(下)

    第六篇 前言 我们在SDWebImageCache(上)中了解了这个缓存类大概的功能是什么?那么接下来就要看看这些功能是如何实现的? 再次强调,不管是图片的缓存还是其他各种不同形式的缓存,在原理上都极 ...

随机推荐

  1. SPEL 表达式解析

    Spring Expression Language 解析器 SPEL解析过程 使用 ExpressionParser 基于 ParserContext 将字符串解析为 Expression, Exp ...

  2. Web.Config全攻略

    一.认识Web.config文件   Web.config 文件是一个xml文本文件,它用来储存 asp.NET Web 应用程序的配置信息(如最常用的设置asp.NET Web 应用程序的身份验证方 ...

  3. MYSQL常见安装错误集:[ERROR] --initialize specified but the data directory has files in it. Abort

    1.[ERROR] --initialize specified but the data directory has files in it. Abort [错误] -初始化指定,但数据目录中有文件 ...

  4. 阶段3 1.Mybatis_06.使用Mybatis完成DAO层的开发_8 properties标签的使用及细节

    properties 可以把数据库链接的配置放在上面的properties里面 #{占位符}的形式去引用上面的.下面的内容就是引用上面的内容的定义. 运行查询的方法测试一下 这样改造可以成功的运行程序 ...

  5. 关于win10系统如何调用debug查看CPU汇编指令和内存

    下载安装DOSBox.网上提供下载地址:DOSBOX Debug是DOS(Disk Operating System,磁盘操作系统).windows提供的实模式(8086方式)程序的调试工具.使用它, ...

  6. 【ABAP系列】SAP ABAP 关于BAPI的EXTENSIONIN 一点解释

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP 关于BAPI的 ...

  7. 【Qt开发】解决Qt程序在Linux下无法输入中文的办法

    解决Qt程序在Linux下无法输入中文的办法 一位网友问我如何在Linux的Qt的应用程序中输入中文,我一开始觉得不是什么问题,但是后面自己尝试了一下还真不行.不仅是Qt制作的应用程序,就连Qt Cr ...

  8. 【Python基础】_2 Python基本语法与常识(迭代优化中...)

    2 Python的基本语法 为了保证Python解释器能顺利编译所编写的代码,也为了程序员对自己和别人所编写的程序易于阅读.维护,对编程语言的语法做一些基本约定是非常必要的. 2.1 编程方式 2.1 ...

  9. Ubuntu 安装nodejs最新版本

    sudo apt update -y   sudo apt install -y npm   sudo npm config set registry https://registry.npm.tao ...

  10. Spring KafkaTemplate 注解式实现 工厂模式

    实现注解式注入kafkaTemplate 生产者和消费者,简化配置文件 目录 消费者工厂 /** * 消费者工厂 */ @EnableKafka @Configuration public class ...