Spark提交做业job的时候要指定该job可使用的CPU、内存等资源参数,生产环境中,任务资源分配不足会致使该job执行中断、失败等问题,因此对Spark的job资源参数分配调优很是重要。html
spark提交做业,yarn-cluster模式示例:并发
./bin/spark-submit\性能
--class com.ww.rdd.wordcount \spa
--master yarn \线程
--deploy-mode cluster \
--executor-memory 4G \
--num-executors 50 \htm
--driver-memory 1G \blog
--conf spark.default.parallelism=1000 \ 队列
--conf spark.memory.fraction=0.75 \ 进程
--conf spark.memory.storageFraction=0.5 \内存
/home/spark/wordcount.jar \
1000 #入参
num-executors
参数说明:该参数用于设置每一个Spark做业总共要用多少个Executor进程来执行。例如Driver向YARN集群管理器申请资源时,YARN集群管理器会尽量按照该配置在集群的各个worker节点上启动相应数量的Executor进程。这个参数很是重要,若是不设置的话,Spark默认只启动少许的Executor进程,意味着该Spark做业并行度不足,若是做业计算多、数据很大,会致使运行速度很是慢甚至资源不足,异常中断,没法完成等。
调优建议:num-executors设置太少或太多的Executor进程都很差。设置的太少,没法充分利用集群资源;设置的太多的话,大部分队列可能没法给予充分的资源。生产环境摸索的经验是每一个Spark做业的运行通常设置50~100个左右的Executor进程比较合适。
executor-memory
参数说明:该参数用于设置每一个Executor进程的内存。Executor内存的大小,不少时候直接决定了Spark做业的性能,并且跟常见的JVM OOM异常,也有直接的关系。
调优建议:若是内存资源充足的前提下,通常每一个job给每一个Executor进程的内存设置4G~8G较为合适,供参考。具体的设置还得根据Spark集群能够占用的内存资源总量来定。num-executors * executor-memory,是本Spark做业申请到的内存资源量,这个值是不能超过Spark集群能够占用的内存资源总量的。
executor-cores
参数说明:该参数用于设置每一个Executor进程的CPU cores数量。这个参数决定了每一个Executor进程并行执行task线程的能力。由于每一个CPU core同一时间只能执行一个task线程,所以每一个Executor进程的CPU cores数量越多,越可以快速地并行执行完分配给本身的全部task线程。
调优建议:若是CPU核数资源充足的前提下,通常每一个job给每一个Executor的CPU core数量设置为2~4个较为合适,供参考。具体的设置还得根据Spark集群能够占用的CPU core数量资源总量来定。num-executors * executor-cores,是本Spark做业申请到的CPU core数量,这个值是不能超过Spark集群能够占用的CPU core数量资源总量的。
driver-memory
参数说明:该参数用于设置Driver进程的内存。
调优建议:Driver的内存一般来讲不设置,或者设置1G左右应该就够了。惟一须要注意的一点是,若是须要使用collect算子将RDD的数据所有拉取到Driver上进行处理,那么必须确保Driver的内存足够大,不然会出现OOM内存溢出的问题。
spark.default.parallelism
参数说明:该参数用于设置每一个stage的默认task数量。这个参数极为重要,若是不设置可能会直接影响Spark做业性能。
调优建议:若是不设置这个参数,会致使Spark本身根据底层HDFS的block数量来设置task的数量,默认是一个HDFS block对应一个task。一般来讲,Spark默认设置的数量是偏少的(好比就几十个task),若是task数量偏少的话,就会致使你前面设置好的Executor的参数都前功尽弃。试想一下,不管Executor进程有多少个,内存和CPU资源分配有多充足,可是task只有1个或者10个,那么90%的Executor进程可能根本就没有task执行,也就是白白浪费了宝贵的内存和CPU资源!所以Spark官网建议的设置原则是,设置该参数为num-executors * executor-cores的2~3倍较为合适,例如,Executor的总CPU core数量为300个,那么设置1000个task是能够的,此时能够充分地利用Spark集群的资源,也就是说,1个cpu core并发跑2~3个task是较为合适的。
spark.memory.fraction、spark.memory.storageFraction
参数说明和调优建议:参见个人另一篇文章 【Spark调优】内存模型与参数调优
上一篇:【Spark调优】Kryo序列化