我们来说下在Spark中的常见配置,关于配置,我们主要从三个角度来讲解,分别是内存,CPU,磁盘三个角度
首先打开Spark的configuration 页面,可以看到所有能找到的Spark配置项
不过配置项由于数量过大,所以我们只会讲解一些重点的配置项,这些配置项虽然Spark官方会给出一些默认配置,但是想要更加符合自身需求,还是需要根据自己的实际情况设置
1. 内存
首先要说的就是内存,不过这一个我们之前说过,Spark的内存可以划分为四个部分,Reserved Memory,User Memory,Exection Memory和Storage Memory
其中的配置项则是主要有
Spark.executor.memory,Spark.memory.fraction,spark.memory.stroageFraction
首先是spark.executor.memory,这是一个绝对值,规定了整个JVM Heap大小,但是由于Reserved Memory固定占用了300MB,所以,需要注意剩余部分需要在spark.executor.memory基础上减去300MB,然后是spark.memory.fraction,标明可以给UserMemory的大小,对于UserMemory,是负责存储用户自定义的数据结构,如果一个应用中没有这么多的自定义对象或者集合数据,就可以将spark.memory.fraction的值设置的距离1越近越好。
还有就是spark.memory.stroageFraction,虽然Spark提供了统一的动态内存管理模式,在资源没有用尽的时候,Execution Memory 和Storage Memory可以互相抢占。但是还是需要我们设置这样一个配置项来说明我们倾向于哪一方
如果我们的数据很少有复用的情况,那么可以压缩Storage Memory,来把内存空间留给Execution Memory
但是如果应用场景是机器学习或者图计算等需要反复利用数据的场景,则是可以将这个参数设置的大一些,让Storage Memory有足够的内存空间
2. CPU
在讲解了内存之后,我们可以来看下CPU,毕竟CPU才是计算的实际执行者,需要增大CPU的利用率,而在Spark中,和CPU相关的参数主要有两个,分别是spark。Executor。instances和spark.executor.cores,前者指定了集群内部的Executors个数,后者规定了每个Executors可用的CPU cores
一个CPU Core在一个分布式任务,因此,一个集群可以承担多少的并发计算,就由spark.exuector.instances和spark.executor.cores的乘积来决定,也就是并发度
而一个任务关联的数据集可以拆分为多个数据集,这些就是并行度,数据拆分粒度越大,数据分片越多,并行度越大,并行度相关的配置项也有两个,分别是spark.default.parallelism和spark.sql.shuffle.partitions,前者定义了SparkContext.parallelize API生成的RDD默认并行度,后者则是Shuffle过程中,Shuffle Read阶段的默认并行度
上面两者,一个是并发度,构建了整个架构的计算资源,一个并行度,构建了每个任务所需的计算资源,一个是供给,一个是需求。
那么两者之间的关系可以概括为
如果一个任务,总共需要内存D,而并行度则是P,那么D/P则是单个数据分片的存储大小
而Execution Memory的内存大小为m,spark.executor.cores设置的单个节点CPU数量为c
那么可以使用下面的公式进行量化
D/P 最好接近 m/c
3. 磁盘
关于磁盘则简单的多,我们需要关注的只有spark.local.dir这一个配合项,主要和本地文件系统相关,默认值是/tmp目录
其中存储了各种临时数据,比如Shuffle中间文件,RDD Cache等
如果需要配置,则是应该将其设置到一个速度更快,空间更大的磁盘上,比如一个大容量的SSD
最后我们说下配置项的设置方式
在Spark中对于配置项可以有三种配置方式
分别是在集群粒度配置spark-defaults.conf,命令行参数以及SparkConf对象
对于配置文件,这个文件存储在Spark安装目录i啊的conf子目录,以Key,Value配置了配置项
但是这一级别只能设置一个全局的配置,如果我们希望设置一个应用级别的,则可以设置命令行或者SparkConf对象
对于命令行参数,是指的运行spark-shell或者spark-submit命令之后,通过-conf关键字来设置配置项,比如
Spark-shell –master local[*] –conf spark.executor.cores=2
这种方式设置的配置项优先级别高于配置文件,但是设置比较困难
所以还有着SparkConf对象进行设置的方式
比如我们想要设置一个SparkConf对象
则是可以如下方式
import org.apache.spark.SparkConf
val conf = new SparkConf()
conf.set(“spark.executor.cores”, “2”)
conf.set(“spark.executor.memory”, “4g”)
conf.set(“spark.local.dir”, “/ssd_fs/large_dir”)
通过这种方式,可以设置应用级别的配置项
那么总结一下,我们从CPU,内存,磁盘三个方案,说明了三者的关系
并且说明了三种配置方式,分别是全局的spark-defaults.conf配置文件,以及适用于单应用的命令行参数和SparkConf对象。