Spark面试题(六)——Spark资源调优

2021年11月26日 阅读数:9
这篇文章主要向大家介绍Spark面试题(六)——Spark资源调优,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

Spark系列面试题

一、资源运行状况

资源调优

二、资源运行中的集中状况

(1)实践中跑的Spark job,有的特别慢,查看CPU利用率很低,能够尝试减小每一个executor占用CPU core的数量,增长并行的executor数量,同时配合增长分片,总体上增长了CPU的利用率,加快数据处理速度。
(2)发现某job很容易发生内存溢出,咱们就增大分片数量,从而减小了每片数据的规模,同时还减小并行的executor数量,这样相同的内存资源分配给数量更少的executor,至关于增长了每一个task的内存分配,这样运行速度可能慢了些,可是总比OOM强。
(3)数据量特别少,有大量的小文件生成,就减小文件分片,不必建立那么多task,这种状况,若是只是最原始的input比较小,通常都能被注意到;可是,若是是在运算过程当中,好比应用某个reduceBy或者某个filter之后,数据大量减小,这种低效状况就不多被留意到。web

三、运行资源优化配置

一个CPU core同一时间只能执行一个线程。而每一个Executor进程上分配到的多个task,都是以每一个task一条线程的方式,多线程并发运行的。
一个应用提交的时候设置多大的内存?设置多少Core?设置几个Executor?面试

 ./bin/spark-submit \  
--master yarn-cluster \  
--num-executors 100 \  
--executor-memory 6G \  
--executor-cores 4 \  
--driver-memory 1G \  
--conf spark.default.parallelism=1000 \  
--conf spark.storage.memoryFraction=0.5 \  
--conf spark.shuffle.memoryFraction=0.3

3.1 运行资源优化配置 -num-executors

参数说明:该参数用于设置Spark做业总共要用多少个Executor进程来执行。Driver在向YARN集群管理器申请资源时,YARN集群管理器会尽量按照你的设置来在集群的各个工做节点上,启动相应数量的Executor进程。这个参数很是之重要,若是不设置的话,默认只会给你启动少许的Executor进程,此时你的Spark做业的运行速度是很是慢的。
参数调优建议:每一个Spark做业的运行通常设置50~100个左右的Executor进程比较合适,设置太少或太多的Executor进程都很差。设置的太少,没法充分利用集群资源;设置的太多的话,大部分队列可能没法给予充分的资源。缓存

3.2 运行资源优化配置 -executor-memory

参数说明:该参数用于设置每一个Executor进程的内存。Executor内存的大小,不少时候直接决定了Spark做业的性能,并且跟常见的JVM OOM异常,也有直接的关联。
参数调优建议每一个Executor进程的内存设置4G~8G较为合适。可是这只是一个参考值,具体的设置仍是得根据不一样部门的资源队列来定。能够看看本身团队的资源队列的最大内存限制是多少,num-executors * executor-memory,是不能超过队列的最大内存量的。此外,若是你是跟团队里其余人共享这个资源队列,那么申请的内存量最好不要超过资源队列最大总内存的1/3~1/2,避免你本身的Spark做业占用了队列全部的资源,致使别的同事的做业没法运行。bash

3.3 运行资源优化配置 -executor-cores

参数说明:该参数用于设置每一个Executor进程的CPU core数量。这个参数决定了每一个Executor进程并行执行task线程的能力。由于每一个CPU core同一时间只能执行一个task线程,所以每一个Executor进程的CPU core数量越多,越可以快速地执行完分配给本身的全部task线程。
参数调优建议:Executor的CPU core数量设置为2~4个较为合适。一样得根据不一样部门的资源队列来定,能够看看本身的资源队列的最大CPU core限制是多少,再依据设置的Executor数量,来决定每一个Executor进程能够分配到几个CPU core。一样建议,若是是跟他人共享这个队列,那么num-executors * executor-cores不要超过队列总CPU core的1/3~1/2左右比较合适,也是避免影响其余同事的做业运行。多线程

3.4 运行资源优化配置 -driver-memory

参数说明:该参数用于设置Driver进程的内存
参数调优建议:Driver的内存一般来讲不设置,或者设置1G左右应该就够了。惟一须要注意的一点是,若是须要使用collect算子将RDD的数据所有拉取到Driver上进行处理(或者是用map side join操做),那么必须确保Driver的内存足够大,不然会出现OOM内存溢出的问题。并发

3.5 运行资源优化配置 -spark.default.parallelism

参数说明:该参数用于设置每一个stage的默认task数量,也能够认为是分区数。这个参数极为重要,若是不设置可能会直接影响你的Spark做业性能。
参数调优建议:Spark做业的默认task数量为500~1000个较为合适。不少人常犯的一个错误就是不去设置这个参数,那么此时就会致使Spark本身根据底层HDFS的block数量来设置task的数量,默认是一个HDFS block对应一个task。一般来讲,Spark默认设置的数量是偏少的(好比就几十个task),若是task数量偏少的话,就会致使你前面设置好的Executor的参数都前功尽弃。试想一下,不管你的Executor进程有多少个,内存和CPU有多大,可是task只有1个或者10个,那么90%的Executor进程可能根本就没有task执行,也就是白白浪费了资源!所以Spark官网建议的设置原则是,设置该参数为num-executors * executor-cores的2~3倍较为合适,好比Executor的总CPU core数量为300个,那么设置1000个task是能够的,此时能够充分地利用Spark集群的资源。ide

3.6 运行资源优化配置 -spark.storage.memoryFraction

参数说明:该参数用于设置RDD持久化数据在Executor内存中能占的比例,默认是0.6。也就是说,默认Executor 60%的内存,能够用来保存持久化的RDD数据。根据你选择的不一样的持久化策略,若是内存不够时,可能数据就不会持久化,或者数据会写入磁盘。
参数调优建议:若是Spark做业中,有较多的RDD持久化操做,该参数的值能够适当提升一些,保证持久化的数据可以容纳在内存中。避免内存不够缓存全部的数据,致使数据只能写入磁盘中,下降了性能。可是若是Spark做业中的shuffle类操做比较多,而持久化操做比较少,那么这个参数的值适当下降一些比较合适。此外,若是发现做业因为频繁的gc致使运行缓慢(经过spark web ui能够观察到做业的gc耗时),意味着task执行用户代码的内存不够用,那么一样建议调低这个参数的值。性能

3.7 运行资源优化配置 -spark.shuffle.memoryFraction

参数说明:该参数用于设置shuffle过程当中一个task拉取到上个stage的task的输出后,进行聚合操做时可以使用的Executor内存的比例,默认是0.2。也就是说,Executor默认只有20%的内存用来进行该操做。shuffle操做在进行聚合时,若是发现使用的内存超出了这个20%的限制,那么多余的数据就会溢写到磁盘文件中去,此时就会极大地下降性能。
参数调优建议:若是Spark做业中的RDD持久化操做较少,shuffle操做较多时,建议下降持久化操做的内存占比,提升shuffle操做的内存占比比例,避免shuffle过程当中数据过多时内存不够用,必须溢写到磁盘上,下降了性能。此外,若是发现做业因为频繁的gc致使运行缓慢,意味着task执行用户代码的内存不够用,那么一样建议调低这个参数的值。优化

总结
一、num-executors:应用运行时executor的数量,推荐50-100左右比较合适
二、executor-memory:应用运行时executor的内存,推荐4-8G比较合适
三、executor-cores:应用运行时executor的CPU核数,推荐2-4个比较合适
四、driver-memory:应用运行时driver的内存量,主要考虑若是使用map side join或者一些相似于collect的操做,那么要相应调大内存量
五、spark.default.parallelism:每一个stage默认的task数量,推荐参数为num-executors * executor-cores的2~3倍较为合适
六、spark.storage.memoryFraction:每个executor中用于RDD缓存的内存比例,若是程序中有大量的数据缓存,能够考虑调大整个的比例,默认为60%
七、spark.shuffle.memoryFraction:每个executor中用于Shuffle操做的内存比例,默认是20%,若是程序中有大量的Shuffle类算子,那么能够考虑其它的比例ui