Spark 参数说明

前言

本篇的主要阐述了Spark 各个参数的使用场景,以及使用的说明与参考;其实主要就是对 Spark 运行过程中各个使用资源的地方,通过调节各种参数来优化资源使用的效率,从而提升Spark作业的执行性能。首先通过大致的 Spark 任务提交流程了解,然后再介绍说明 Spark 各个参数的使用方式,这样更有利于熟悉了解。

Spark Job 提交

Spark Job 提交流程

Executor资源分配

  1. spark-submit提交 Spark 作业之后,就会启动一个对应的 Driver;不同运行模式 Driver 可能在本地启动,也有可能在集群中某个节点启动;
  2. Driver 开始向集群资源管理器(YARN)申请 Executor 进程,其中包括一定数量 CPU core 与内存(根据 Spark 作业设置的参数分配资源);
  3. 申请到资源之后 Driver 就会开始调度、执行 Spark 作业代码,并将 Spark 作业代码拆分成多个 Stage(链接:stage划分原理);一个 Stage 会创建多个 Task ,这些 Task 会分配到各个节点的 Executor 进程中执行( Task 是最小的计算单元,同一类的 Task 负责计算 Stage 中相同逻辑代码,每一个处理的数据会不一样);
  4. Executor 的内存主要分为三部分:第一部分是让 Task 执行 Spark 作业代码使用(默认是占 Executor总内存的 20%);第二部分是 Task 通过 Shuffle 过程拉取了上一个 Stage 的 Task 输出结果,进行聚合等操作时使用(默认也是占 Executor 总内存的 20%);第三部分是 RDD 持久化时使用(默认占 Executor 总内存的 60%);
  5. 所有 Stage 执行完成之后,Driver 就会将结果返回;

Spark Job提交参数说明

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


num-executors:该作业总共需要多少executor进程执行 
#建议:每个作业运行一般设置5,10,20个左右较合适 
executor-memory:设置每个executor进程的内存, num-executors * numexecutors 代表作业申请的总内存量(尽量不要超过最大总内存的1/3~1/2)
#建议:设置5G~10G较合适
executor-cores:每个executor进程的CPU Core 3数量[1-5],该参数决定每个 executor进程并行执行task线程的能力, num-executors* executor-cores代表 作业申请总 CPU core数(不要超过总 CPU Core的 1/3~1/2 ) 
#建议:设置2~4个比较合适
driver-memory:设置Driver进程的内存
#建议:通常不用设置,一般 4G 就够了,若出现使用 collect 算子将 RDD 数据全部拉取到 Driver 上处理,就必须确 保该值足够大,否则 OOM 内存溢出(如果设置了广播变量再设置大一点)。
spark.default.parallelism:每个 stage 的默认 task 数量
#建议:设置 500~1000 较合适,默认一个 HDFS 的 block 对应一个 task,Spark默认值偏少,这样导致不能充分利用资源
spark.shuffle.memoryFraction(默认值:0.2)
#建议:如果持久化操作较少,但 shuffle 较多时,可以降低持久化内存占比,提高 shuffle 操作内存占比(提高执行效率)。
应用程序参数

num-executors

参数说明:该参数用于设置 Spark Job 需要多少个 Executor 进程运行,Driver 在向 YARN 集群管理器申请资源时,YARN 集群管理器会在集群的各个工作节点上,启动相应数量的 Executor 进程(默认会设置少量的)。

参数调优建议:每个 Spark 作业的运行一般设置 50~100 个左右的 Executor 进程比较合适,设置的太少,无法充分利用集群资源;设置的太多的话,大部分队列可能无法给予充分的资源(上100G的话设置100~200)。

executor-memory

参数说明:该参数用于设置每个 Executor 进程的内存,Executor 内存的大小,很多时候直接决定了 Spark 作业的性能,与常见的 JVM OOM 异常有直接的关联。

参数调优建议:每个 Executor 进程的内存设置 4G/8G 较为合适,num-executors * executor-memory 代表 Spark 作业申请到的总内存量(所有Executor进程的内存总和),总量不能超过队列的最大内存量。如果你是跟团队里其他人共享这个资源队列,那么申请的总内存量最好不要超过资源队列最大总内存的1/3~1/2,避免你自己的Spark作业占用了队列所有的资源,导致别的 Spark 作业无法运行。

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左右比较合适,避免影响其他 Spark 作业运行。

driver-memory

参数说明:该参数用于设置Driver进程的内存。

参数调优建议:Driver的内存通常来说不设置,或者设置 1G 左右,如果需要使用 collect 算子将 RDD 的数据全部拉取到 Driver 上进行处理,那么必须确保 Driver 的内存足够大,否则会出现 OOM 内存溢出的问题。

spark.driver.cores

默认值:1

参数说明:Driver端分配的核数。

调优建议:Thriftserver是启动 Thriftserver服务的机器,资源充足的话可以尽量给多。

spark.driver.memory

默认值:1G

参数说明:Driver端分配的内存数。在 Client 模式下不能直接通过 SparkConf配置(JVM驱动已经启动了),但是可以通过 --driver-memory来设置。

spark.executor.memory

默认值:1G

参数说明:每个Executor分配的内存数。

调优建议:会受到yarn CDH的限制,和MemoryOverhead相加不能超过总内存限制

spark.driver.maxResultSize

默认值:1G(最小1MB,设置0为无限)

参数说明:Driver端接收的最大结果大小,如果总大小超过此限制作业会被终止。

调优建议:不建议设置的太大,如果要做数据可视化,更应该控制在20-30MB以内。(过大会导致OOM)

spark.extraListeners

默认值:none

参数说明:随着SparkContext被创建而创建,用于监听单参数、无参数构造函数的创建,并抛出异常(实现 SparkListener 的类的逗号分隔列表)。

Shuffle 过程参数

spark.shuffle.file.buffer

默认值:32k

参数说明:该参数用于设置 shuffle write task 的 BufferedOutputStream 的 buffer 缓冲大小。将数据写到磁盘文件之前,会先写入buffer缓冲中,待缓冲写满之后,才会溢写到磁盘。

调优建议:如果作业可用的内存资源较为充足的话,可以适当增加这个参数的大小(比如64k),从而减少 shuffle write 过程中溢写磁盘文件的次数,也就可以减少磁盘 IO 次数,进而提升性能。在实践中发现,合理调节该参数,性能会有 1%~5% 的提升。

spark.shuffle.io.maxRetries

默认值:3

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

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

spark.shuffle.io.retryWait

默认值:5s

参数说明:具体解释同上,该参数代表了每次重试拉取数据的等待间隔。

调优建议:建议加大间隔时长(比如60s),以增加shuffle操作的稳定性。

spark.shuffle.sort.bypassMergeThreshold

默认值:200

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

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

spark.shuffle.consolidateFiles

默认值:false

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

调优建议:如果的确不需要 SortShuffleManager 的排序机制,那么除了使用 bypass机制,还可以尝试将 spark.shffle.manager 参数手动指定为hash,使用 HashShuffleManager,同时开启 consolidate 机制。在实践中尝试过,发现其性能比开启了 bypass 机制的 SortShuffleManager 要高出 10%~30%。

spark.shuffle.compress

默认值:true

参数说明:是否压缩map输出文件。

spark.shuffle.spill.compress

默认值:true

参数说明:shuffle过程中溢出的文件是否压缩(压缩方式:spark.io.compression.codec)

spark.shuffle.manager

默认值:sort

参数说明:该参数用于设置ShuffleManager的类型。Spark 1.5以后,有三个可选项:hash、sort 和 tungsten-sort。HashShuffleManager 是Spark 1.2以前的默认选项,但是Spark 1.2以及之后的版本默认都是SortShuffleManager了。tungsten-sort 与 sort类似,但是使用了 tungsten 计划中的堆外内存管理机制,内存使用效率更高。

调优建议:由于 SortShuffleManager 默认会对数据进行排序,因此如果你的业务逻辑中需要该排序机制的话,则使用默认的 SortShuffleManager;而如果你的业务逻辑不需要对数据进行排序,那么建议参考后面的几个参数调优,通过 bypass 机制或优化的HashShuffleManager 来避免排序操作,同时提供较好的磁盘读写性能。

spark.shuffle.memoryFraction

默认值:0.2

参数说明:该参数用于设置 shuffle 过程中一个 task 拉取到上个 stage 的 task 的输出后,进行聚合操作时能够使用的 Executor 内存的比例,默认是0.2。Executor 默认只有 20% 的内存用来进行该操作;shuffle 操作在进行聚合时,如果发现使用的内存超出了 20% 的限制,那么多余的数据就会溢写到磁盘文件中去,此时就会极大地降低性能。

参数调优建议:如果 Spark 作业中的 RDD 持久化操作较少,shuffle 操作较多时,建议降低持久化操作的内存占比,提高shuffle操作的内存占比比例,避免shuffle过程中数据过多时内存不够用,必须溢写到磁盘上,降低了性能。如果发现作业由于频繁的 GC导致运行缓慢,意味着 task 执行用户代码的内存不够用,那么同样建议调低这个参数的值。

spark.reducer.maxSizeInFlight

默认值:48m

参数说明:该参数用于设置 shuffle read task 的 buffer 缓冲大小, buffer 缓冲决定了每次能够拉取多少数据。从每个 reduce 任务同时拉取的最大 map 数,每个 reduce 都会在完成任务后,需要一个堆外内存的缓冲区来存放结果,如果没有充裕的内存就尽可能把这个调小一点。相反,堆外内存充裕,调大些就能节省 GC时间。

调优建议:如果作业可用的内存资源较为充足的话,可以适当增加参数的大小(比如 96M),从而减少拉取数据的次数,也就可以减少网络传输的次数,进而提升性能。在实践中发现,合理调节该参数,性能会有 1%~5% 的提升。

缺点:容易出现 reduce oom,reduce task 去 map 拉取数据,reduce 一边拉数据一边聚合 reduce段有一块聚合内存(executor memory * 0.2)

解决办法

  1. 增加reduce 聚合的内存的比例 设置spark.shuffle.memoryFraction;
  2. 增加executor memory的大小 --executor-memory 5G;
  3. 减少reduce task每次拉取的数据量 设置spark.reducer.maxSizeInFlight 24m;

spark.reducer.maxBlocksInFlightPerAddress

默认值:Int.MaxValue

参数说明:限制了每个主机每次Reduce可以被多少台远程主机拉取文件块,调低这个参数可以有效减轻Node Manager的负载。

spark.reducer.maxReqsInFlight

默认值:Int.MaxValue

参数说明:限制远程机器拉取本机器文件块的请求数,随着集群增大,需要对此做出限制。否则可能会使本机负载过大而挂掉。

spark.reducer.maxReqSizeShuffleToMem

默认值:200M

参数说明:请求的文件大小高于此阈值时,会被强行溢写到产品上,防止一大堆并发请求把内存占满。

压缩与序列化参数

spark.broadcast.compress

默认值:true

参数说明:广播变量前是否会先进行压缩。(压缩方式:spark.io.compression.codec)

内存管理参数

spark.default.parallelism

参数说明:该参数用于设置每个 stage 的默认 task 数量。这个参数很重要,如果不设置可能会直接影响 Spark 作业性能。

参数调优建议:Spark 作业的默认 task 数量为 500~1000 个较为合适。如果这个参数没有设置,那么Spark会根据底层 HDFS 的 block 数量来设置task的数量(一个HDFS block 对应一个 task )。如果 task 数量偏少的话,设置的Executor进程有多少个,内存和CPU有多大,但是 task 只有1个或者 10 个,那么 90% 的 Executor 进程可能根本就没有 task 执行,就会造成资源的浪费。因此 Spark 官网建议的设置原则是,设置该参数为 num-executors * executor-cores 的 2~3 倍较为合适,比如 Executor 的总 CPU core 数量为 300 个,那么设置 1000 个 task 是可以充分地利用Spark集群的资源。

spark.storage.memoryFraction

默认值:0.6

参数说明:该参数用于设置 RDD 持久化数据在 Executor 内存中能占的比例,默认 Executor 60% 的内存,可以用来保存持久化的 RDD 数据。根据你选择的不同的持久化策略,如果内存不够时,可能数据就不会持久化,或者数据会写入磁盘。

参数调优建议:如果 Spark 作业中,有较多的 RDD 持久化操作,该参数的值可以适当提高一些,保证持久化的数据能够容纳在内存中。避免内存不够缓存所有的数据,导致数据只能写入磁盘中,降低了性能。但是如果 Spark 作业中的 shuffle 类操作比较多,而持久化操作比较少,那么这个参数的值适当降低一些比较合适。此外,如果发现作业由于频繁的 GC 导致运行缓慢(通过spark web ui可以观察到作业的 GC耗时),意味着 task 执行用户代码的内存不够用,那么同样建议调低这个参数的值。


参考链接:
https://tech.meituan.com/2016/05/12/spark-tuning-pro.html
https://spark.apache.org/docs/2.2.0/configuration.html
https://people.apache.org/~pwendell/spark-releases/spark-2.2.0-rc4-docs/configuration.html

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 非常感谢您的提问。以下是关于Spark性能调优系列的回答: Spark性能调优是一个非常重要的话题,它可以帮助我们更好地利用Spark的优势,提高我们的数据处理效率。在Spark中,参数配置是非常重要的一环,因为它可以直接影响到Spark的性能表现。在官网上,我们可以找到一份完整的Spark参数配置大全,它包含了所有的Spark参数配置项,以及每个参数的详细说明和建议配置值。这份资料可以帮助我们更好地理解Spark参数配置,以及如何根据我们的需求来进行参数调优。 在使用Spark时,我们应该根据自己的数据量、集群规模、任务类型等因素来进行参数配置。例如,对于内存使用方面,我们可以通过调整spark.driver.memory和spark.executor.memory参数来控制内存的使用量;对于任务并行度方面,我们可以通过调整spark.default.parallelism和spark.sql.shuffle.partitions参数来控制任务的并行度;对于数据读取方面,我们可以通过调整spark.sql.files.maxPartitionBytes和spark.sql.files.openCostInBytes参数来优化数据读取性能等等。 总之,Spark参数配置是一个非常重要的话题,我们应该根据自己的需求来进行参数调优,以达到最佳的性能表现。希望以上回答能够对您有所帮助。 ### 回答2: Spark是一款强大的分布式计算框架,它具有高效的计算速度和可扩展性,能够处理规模庞大的数据集。然而,为了获得更好的性能,我们需要对Spark进行参数调优。本文将介绍Spark参数配置大全,旨在帮助大家更好地调优Spark。 1. Spark Executor参数 1.1 spark.executor.memory: Executor进程的内存大小,该参数会影响到该计算节点可以处理的数据量,一般设置为节点内存的75%左右。 1.2 spark.executor.cores: Executor进程的CPU核心数,该参数会影响到该计算节点可以处理的任务数量,一般设置为CPU核心数的1-4倍。 1.3 spark.executor.instances: 运行的Executor进程实例数量,一般设置为总CPU核心数的4-8倍。 1.4 spark.locality.wait: Executor为了处理数据优先从哪个位置获取数据,可以设置为PROCESS_LOCAL、NODE_LOCAL、RACK_LOCAL等。 2. Spark Driver参数 2.1 spark.driver.memory: Driver进程的内存大小,该参数决定了整个Spark应用程序可以处理的数据量,一般设置为节点内存的50%左右。 2.2 spark.driver.cores: Driver进程的CPU核心数,该参数决定了驱动程序可以并行处理的任务数。 2.3 spark.driver.maxResultSize: 驱动程序可以接受的结果集大小限制,如果超出限制则会出现oom的问题。 3. Spark Shuffle参数 3.1 spark.shuffle.spill.compress: Shuffle写入磁盘之前是否压缩。 3.2 spark.shuffle.file.buffer: Shuffle写入磁盘之前的Buffer大小,一般为32MB。 3.3 spark.shuffle.io.maxRetries: Shuffle读取磁盘数据时最大重试次数。 3.4 spark.shuffle.sort.bypassMergeThreshold: 内存中的排序文件大小达到多少时跳过合并。 4. Spark Memory参数 4.1 spark.memory.fraction: Executor进程中使用的内存比例。 4.2 spark.memory.storageFraction: 持久化RDD使用的内存比例。 4.3 spark.memory.offHeap.enabled: 是否启用OffHeap内存,OffHeap内存分配和释放速度更快,但不能直接被JVM管理。 4.4 spark.storage.memoryFraction: RDD数据存储在内存中的占比。 5. Spark Task参数 5.1 spark.task.maxFailures: Task最大失败次数。 5.2 spark.task.cpus: Task使用的CPU核心数。 5.3 spark.task.resource.gpu.amount:使用GPU的时候设置。 本文仅列举了Spark的一些常见配置参数,更多参数可以在官网上查看。通过不断的调优优化,可以有效地提高Spark的性能和计算效率,让我们的计算任务更加高效。 ### 回答3: Spark是目前流行的分布式计算框架之一,作为一个分布式计算框架,其性能调优是非常重要的。针对这一点,Spark提供了大量的参数来进行配置,我们可以根据应用场景进行调优,以达到最佳的性能表现。 1. 堆内存设置:我们可以通过设置spark.driver.memory和spark.executor.memory来控制任务在执行过程中所需要的内存,比如设置为1G或2G,都是比较合适的。 2. 并发度调整:我们可以通过设置spark.default.parallelism和spark.sql.shuffle.partitions来修改默认的并发度,提高任务的并行性能。 3. 序列化设置:Spark支持Java序列化和Kyro序列化,如果数据量较大,推荐使用Kyro,而在数据量比较小的情况下,Java序列化的速度可能会更快。 4. 垃圾回收机制:Spark采用的是JVM垃圾回收机制,默认情况下是使用并行垃圾回收器,可以通过修改spark.executor.extraJavaOptions来调整垃圾回收器的参数。 5. 数据压缩设置:在数据传输过程中,我们可以将数据压缩以减小数据传输的大小,这可以通过设置spark.io.compression.codec来完成。 6. 内存管理策略:Spark提供了两种内存管理策略,即静态内存管理和动态内存管理,可通过设置spark.memory.useLegacyMode和spark.memory.fraction来选择合适的策略。 7. 代码优化:为了提高Spark的性能,我们可以通过代码优化来减少读写IO和数据扫描的次数,使用Broadcast变量等来减少数据传输的次数,从而提高性能。 总之,在对Spark进行性能调优时,需要根据具体的应用场景进行常规的参数设置以及代码优化,以达到最优的性能表现,从而更好地支持大数据分析和处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值