参考链接:
http://bcxw.net/article/136.html
一 .spark on yarn 部署优化
启动Spark任务时,在没有配置spark.yarn.archive或者spark.yarn.jars时, 会看到不停地上传jar,非常耗时;使用spark.yarn.archive可以大大地减少任务的启动时间,整个处理过程如下。
1、进入到spark的jars目录
2、HDFS上创建存放spark jar目录
hdfs dfs -mkdir -p /spark-yarn/jars
3、将jars下的包上传至刚健的HDFS路径
[hadoop@hadoop jars]$ hdfs dfs -put /opt/spark/jars/* /spark-yarn/jars/
4、在spark-defaults.conf中添加(也可以在启动时候 -conf 指定)
spark.yarn.jars hdfs://ruozedata001:9000/spark-jars/jars/*
二.动态资源分配
spark standalone模式,系统根据机器的数量,核数,来自动启用最大资源来执行任务,当然executor内存还是需要自己配置的,因为默认是1g.
而 spark yarn模式默认只启用2个executor,1 core,那么你再多机器也不能充分利用资源。而spark yarn资源分配又分动态和静态配置两种。
spark yarn动态资源分配策略:
一个spark程序使用轮询来请求资源。具体过程如下:
1).如果程序中有任务在等待,超过spark.dynamicAllocation.schedulerBacklogTimeout参数配置的时间(默认是1s),将会得到新的资源,分配executor
2). 如果等待spark.dynamicAllocation.sustainedSchedulerBacklogTimeout参数配置的时间(默认是1s)后,还有任务在等待,第一步的逻辑将会再次被触发。
注意:每次轮询分配的executor的数目是呈指数增长的:如第一次申请分配1个executor,第二次申请分配2个executor,第n次申请分配2的n-1次方。
资源移除策略:
1).如果spark任务中仍有任务在等待被执行,则这些executor将不会被判定为空闲的。
2).经过spark.dynamicAllocation.executorIdleTimeout参数设定的时间(默认是60s),如果executor仍然没有任务,则会被判定为空闲的。
3).如果executor是空闲的,这个资源就可以被回收。
4).安全的移除executor:
在不启用动态分配的模式下,executor将会在程序执行完毕之后移除,这个executor的所有状态都将被废弃。但是在动态分配模式下,在程序没有执行完毕,如果一个executor被移除完毕,程序有可能会读取这个executor存储的一些状态,因此spark需要一种机制来安全的移除executors。这个过程主要是在shuffle过程。在shuffle过程中,executor会将一些输出写到磁盘,然后作为server让其他executors可以获取shuffle的结果文件。为了保护这个过程,spark从1.2开始,提过了一个额外的shuffle服务:org.apache.spark.yarn.network.YarnShuffleService。 如果这个服务启动,executor将会通过这个服务来获取shuffle文件,而不受executor的影响。
spark yarn动态资源分配配置
配置spark-default.conf:
如果开启,不能设置spark.executor.instances(每个机器启动多少个executor)参数
spark.shuffle.service.enabled true //启用External shuffle Service服务
spark.shuffle.service.port 7337 //Shuffle Service默认服务端口,必须和yarn-site中的一致
spark.dynamicAllocation.enabled true //开启动态资源分配
spark.dynamicAllocation.initialExecutors 2 //初始executor数量,如果--num-executors设置的值比这个值大,那么将使用--num-executors设置的值作为初始executor数量。
spark.dynamicAllocation.minExecutors 1 //每个Application最小分配的executor数
spark.dynamicAllocation.maxExecutors 30 //每个Application最大并发分配的executor数
spark.dynamicAllocation.schedulerBacklogTimeout 1s //默认1s
spark.dynamicAllocation.sustainedSchedulerBacklogTimeout 5s //默认1s
配置yarn-site.xml:
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle,spark_shuffle</value>
</property>
<property>
<name>yarn.nodemanager.aux-services.spark_shuffle.class</name>
<value>org.apache.spark.network.yarn.YarnShuffleService</value>
</property>
<property>
<name>spark.shuffle.service.port</name>
<value>7337</value>
</property>
将$SPARKHOME/lib/spark-X.X.X-yarn-shuffle.jar拷贝到每台NodeManager的${HADOOPHOME}/share/hadoop/yarn/lib/下, 重启所有修改配置的节点。
使用动态资源分配,提交任务的时候可以指定–num-executors,也可以不指定
建议如果采用了DRA,可以注意如下几点:
设置一个合理的minExecutors-maxExecutors值
将Executor对应的cpuCore 最好设置为<=3 ,避免Executor数目下降时,等不及新申请到资源,已有的Executor就因为任务过重而导致集群挂掉。
如果程序中有shuffle,例如(reduce,groupBy),建议设置一个合理的并行数,避免杀掉过多的Executors。
对于每个Stage持续时间很短的应用,其实不适合这套机制。这样会频繁增加和杀掉Executors,造成系统颠簸。而Yarn对资源的申请处理速度并不快。
三.spark 参数优化
配置于spark-default.conf
1.spark.yarn.submit.file.replication 3
应用程序上传到HDFS的复制份数
2.spark.preserve.staging.files false
设置为true,在job结束后,将stage相关的文件保留而不是删除。 (一般无需保留,设置成false)
3.spark.yarn.scheduler.heartbeat.interal-ms 5000
Spark application master给YARN ResourceManager 发送心跳的时间间隔(ms)
4.spark.yarn.executor.memoryOverhead 1000
5.spark.serializer org.apache.spark.serializer.KryoSerializer
暂时只支持Java serializer和KryoSerializer序列化方式
6.spark.storage.memoryFraction 0.3
用来调整cache所占用的内存大小。默认为0.6。如果频繁发生Full GC,可以考虑降低这个比值,这样RDD Cache可用的内存空间减少(剩下的部分Cache数据就需要通过Disk Store写到磁盘上了),会带来一定的性能损失,但是腾出更多的内存空间用于执行任务,减少Full GC发生的次数,反而可能改善程序运行的整体性能。
7.spark.sql.shuffle.partitions 800
一个partition对应着一个task,如果数据量过大,可以调整次参数来减少每个task所需消耗的内存.
8.spark.sql.autoBroadcastJoinThreshold -1
当处理join查询时广播到每个worker的表的最大字节数,当设置为-1广播功能将失效。
9.spark.speculation false
如果设置成true,倘若有一个或多个task执行相当缓慢,就会被重启执行。(事实证明,这种做法会造成hdfs中临时文件的丢失,报找不到文件的错)
10.spark.sql.codegen true
Spark SQL在每次执行次,先把SQL查询编译JAVA字节码。针对执行时间长的SQL查询或频繁执行的SQL查询,此配置能加快查询速度,因为它产生特殊的字节码去执行。但是针对很短的查询,可能会增加开销,因为它必须先编译每一个查询
11.spark.shuffle.spill false
如果设置成true,将会把spill的数据存入磁盘
12.spark.shuffle.consolidateFiles true
我们都知道shuffle默认情况下的文件数据为map tasks * reduce tasks,通过设置其为true,可以使spark合并shuffle的中间文件为reduce的tasks数目。
13.代码中 如果filter过滤后 会有很多空的任务或小文件产生,这时我们使用coalesce或repartition去减少RDD中partition数量。
RPC 服务线程调优
当 Spark 同时运行大量的 tasks 时,Driver 很容易出现 OOM,这是因为在 Driver 端的 Netty 服务器上产生大量 RPC 的请求积压,我们可以通过加大 RPC 服务的线程数解决 OOM 问题,比如 spark.rpc.io.serverThreads = 64。
四 spark提交命令
提交命令:
spark-submit
–master yarn
–deploy-mode cluster
–driver-memory 4g
–executor-memory 8g
–driver-cores 4
–executor-cores 4
–num-executors 9
–conf spark.executor.memoryOverhead=6g
–conf spark.default.parallelism=120
–class com.yss.v.WriteDataToTS_SEC_ALL_INFO
/home/work-space/sparkJars/zq-1.0.jar ts_sec_all_info /hfile
driver-memory 配置driver端内存。
driver-cores 配置driver端cpu内核数。
executor-memory 配置每个executor堆内内存。
executor-cores 配置每个executor的cpu内核数。
num-executors 配置executor的个数,如果是cluster模式,实际计算的executor个数为num-executors - 1,因为有一个用于启动driver。
spark.executor.memoryOverhead 设置每个executor堆外内存。
spark.default.parallelism 设置并行度。Spark RDD如果没有手动分区,会采用该参数进行分区,一般设置为每个executor的一个cpu内存执行2-3个task合适,所以并行度为executor个数x内核数x(2~3)
class 程序的main函数所在的类全路径名。
/home/work-space/sparkJars/zq-1.0.jar 程序jar包。
ts_sec_all_info /hfile 程序运行所需要的参数。