spark 参数调优详解(持续更新中)

spark参数调优需要对各个参数充分理解,没有一套可以借鉴的参数,因为每个集群规模都不一样,只有理解了参数的用途,调试出符合自己业务场景集群环境,并且能在扩大集群、业务的情况下,能够跟着修改参数。这样才算是正确的参数调优。

1、背景

使用spark-thriftserver,jdbc连接以执行hive查询。

spark2.2.1版本,其实官方文档中,相关的参数已经写的很详细了,这边仔细阅读了官方文档,

并结合了实际情景,实践之后,整理了这篇博客。

官方文档:

http://spark.apache.org/docs/2.2.1/configuration.html

yarn:

http://spark.apache.org/docs/2.2.1/running-on-yarn.html#configuration

2、参数详解

① Application Properties 应用基本属性

spark.driver.cores  

driver端分配的核数,默认为1,thriftserver是启动thriftserver服务的机器,资源充足的话可以尽量给多。

spark.driver.memory

driver端分配的内存数,默认为1g,同上。

spark.executor.memory

每个executor分配的内存数,默认1g,会受到yarn CDH的限制,和memoryOverhead相加 不能超过总内存限制。

spark.driver.maxResultSize

driver端接收的最大结果大小,默认1GB,最小1MB,设置0为无限。

这个参数不建议设置的太大,如果要做数据可视化,更应该控制在20-30MB以内。

过大会导致OOM。

spark.extraListeners

默认none,随着SparkContext被创建而创建,用于监听单参数、无参数构造函数的创建,并抛出异常。

② Runtime Environment 运行环境

主要是一些日志,jvm参数的额外配置,jars等一些自定义的配置,一般不会用到这一块。

③ Shuffle Behavior 

spark.reducer.maxSizeInFlight

默认48m。从每个reduce任务同时拉取的最大map数,每个reduce都会在完成任务后,需要一个堆外内存的缓冲区来存放结果,如果没有充裕的内存就尽可能把这个调小一点。。相反,堆外内存充裕,调大些就能节省gc时间。

spark.reducer.maxBlocksInFlightPerAddress

限制了每个主机每次reduce可以被多少台远程主机拉取文件块,调低这个参数可以有效减轻node manager的负载。(默认值Int.MaxValue)

spark.reducer.maxReqsInFlight

限制远程机器拉取本机器文件块的请求数,随着集群增大,需要对此做出限制。否则可能会使本机负载过大而挂掉。。(默认值为Int.MaxValue)

spark.reducer.maxReqSizeShuffleToMem

shuffle请求的文件块大小 超过这个参数值,就会被强行落盘,防止一大堆并发请求把内存占满。(默认Long.MaxValue)

spark.shuffle.compress

是否压缩map输出文件,默认压缩 true

spark.shuffle.spill.compress

shuffle过程中溢出的文件是否压缩,默认true,使用spark.io.compression.codec压缩。

spark.shuffle.file.buffer

在内存输出流中 每个shuffle文件占用内存大小,适当提高 可以减少磁盘读写 io次数,初始值为32k

spark.shuffle.memoryFraction

该参数代表了Executor内存中,分配给shuffle read task进行聚合操作的内存比例,默认是20%。

cache少且内存充足时,可以调大该参数,给shuffle read的聚合操作更多内存,以避免由于内存不足导致聚合过程中频繁读写磁盘。

spark.shuffle.manager

当ShuffleManager为SortShuffleManager时,如果shuffle read task的数量小于这个阈值(默认是200),则shuffle write过程中不会进行排序操作,而是直接按照未经优化的HashShuffleManager的方式去写数据,但是最后会将每个task产生的所有临时磁盘文件都合并成一个文件,并会创建单独的索引文件。

当使用SortShuffleManager时,如果的确不需要排序操作,那么建议将这个参数调大一些,大于shuffle read task的数量。那么此时就会自动启用bypass机制,map-side就不会进行排序了,减少了排序的性能开销。但是这种方式下,依然会产生大量的磁盘文件,因此shuffle write性能有待提高。

spark.shuffle.consolidateFiles

如果使用HashShuffleManager,该参数有效。如果设置为true,那么就会开启consolidate机制,会大幅度合并shuffle write的输出文件,对于shuffle read task数量特别多的情况下,这种方法可以极大地减少磁盘IO开销,提升性能。

如果的确不需要SortShuffleManager的排序机制,那么除了使用bypass机制,还可以尝试将spark.shuffle.manager参数手动指定为hash,使用HashShuffleManager,同时开启consolidate机制。

spark.shuffle.io.maxRetries

shuffle read task从shuffle write task所在节点拉取属于自己的数据时,如果因为网络异常导致拉取失败,是会自动进行重试的。该参数就代表了可以重试的最大次数。如果在指定次数之内拉取还是没有成功,就可能会导致作业执行失败。

对于那些包含了特别耗时的shuffle操作的作业,建议增加重试最大次数(比如60次),以避免由于JVM的full gc或者网络不稳定等因素导致的数据拉取失败。在实践中发现,对于针对超大数据量(数十亿~上百亿)的shuffle过程,调节该参数可以大幅度提升稳定性。

spark.shuffle.io.retryWait

同上,默认5s,建议加大间隔时长(比如60s),以增加shuffle操作的稳定性。

spark.io.encryption.enabled + spark.io.encryption.keySizeBits + spark.io.encryption.keygen.algorithm

io加密,默认关闭

④ Spark UI

这一块配置,是有关于spark日志的。日志开关,日志输出路径,是否压缩。

还有一些可视化界面、端口的配置 

 ⑤ Compression and Serialization

spark.broadcast.compress

广播变量前是否会先进行压缩。默认true (spark.io.compression.codec)

spark.io.compression.codec

压缩RDD数据、日志、shuffle输出等的压缩格式 默认lz4

spark.io.compression.lz4.blockSize

使用lz4压缩时,每个数据块大小 默认32k

spark.rdd.compress

rdd是否压缩 默认false,节省memory_cache大量内存 消耗更多的cpu资源(时间)。

spark.serializer.objectStreamReset

当使用JavaSerializer序列化时,会缓存对象防止写多余的数据,但这些对象就不会被gc,可以输入reset 清空缓存。默认缓存100个对象,修改成-1则不缓存任何对象。

⑥ Memory Management

spark.memory.fraction

spark.memory.storageFraction

spark.shuffle.service.enabled=true
shuffle service的目的是保存executor产生的文件并提供给后续任务使用,从而使得executor可以安全的移除
spark.dynamicAllocation.enabled 资源动态分配,多用多拿,不用还回去
spark.dynamicAllocation.minExecutors 动态最小的executor数量
spark.dynamicAllocation.maxExecutors 动态最大的executor数量
spark.dynamicAllocation.schedulerBacklogTimeout 资源不够(有task在pending的时候),间隔多久会去申请额外的资源
spark.dynamicAllocation.sustainedSchedulerBacklogTimeout 首次之后,资源不够时,申请资源间隔
spark.dynamicAllocation.executorIdleTimeout 不用资源多少时间,会kill executor
spark.sql.hive.thriftServer.singleSession 可查看持久化表
spark.yarn.executor.memoryOverhead 每个executor分配的堆外内存,解决报错说将此参数调大。包括了VM开销,交错字符串,其他开销等,会随着executor的大小变化,大小约为它的10%左右。

spark2.3.0+中,分成了2个参数spark.driver.memoryOverhead spark.executor.memoryOverhead


spark.executor.memory 每个executor的执行内存,spark2.0之后,动态分配storage和execution,默认切分0.6。加上堆外内存,不能大于yarn的container内存限制。
spark.yarn.executor.memoryOverhead和spark.executor.memory这两个是比较重要的参数,配置不好,就很容易导致OOM。

spark.executor.cores 

每个executor核数

spark.driver.extraJavaOptions -Dhdp.version=2.6.0-cdh5.8.3 

配置相应的hadoop版本,不然也会kill executor

猜你喜欢

转载自blog.csdn.net/kwame211/article/details/81669730