前言

新来的实习小伙,在公司的一个小集群(14台服务器,用于处理一些数据量较小的月数据)上面提交了一个spark application,然后其他人提交的application都在排队中,一个个的在抱怨。我看了一下小伙的提交脚本,然后问:为什么设置这样的配置?实习生脸一红:网上copy的…我也不知道该怎么设置,这个究竟该怎么分配呢?

所有的调优都请参考两篇博客

Spark性能优化指南——基础篇
Spark性能优化指南——高级篇

这里还是得感谢美团技术博客在三年前写的这两篇博客,真的是几乎涵盖了所有的调优技巧

资源参数调优理论篇

了解完了Spark作业运行的基本原理之后,对资源相关的参数就容易理解了。所谓的Spark资源参数调优,其实主要就是对Spark运行过程中各个使用资源的地方,通过调节各种参数,来优化资源使用的效率,从而提升Spark作业的执行性能。以下参数就是Spark中主要的资源参数,每个参数都对应着作业运行原理中的某个部分,我们同时也给出了一个调优的参考值。

num-executors

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

executor-memory

参数说明:该参数用于设置每个Executor进程的内存。Executor内存的大小,很多时候直接决定了Spark作业的性能,而且跟常见的JVM OOM异常,也有直接的关联。
参数调优建议:每个Executor进程的内存设置4G8G较为合适。但是这只是一个参考值,具体的设置还是得根据不同部门的资源队列来定。可以看看自己团队的资源队列的最大内存限制是多少,num-executors乘以executor-memory,是不能超过队列的最大内存量的。此外,如果你是跟团队里其他人共享这个资源队列,那么申请的内存量最好不要超过资源队列最大总内存的1/31/2,避免你自己的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左右比较合适,也是避免影响其他同学的作业运行。

driver-memory

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

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集群的资源。

spark.storage.memoryFraction

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

spark.shuffle.memoryFraction

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

资源参数的调优,没有一个固定的值,需要同学们根据自己的实际情况(包括Spark作业中的shuffle操作数量、RDD持久化操作数量以及spark web ui中显示的作业gc情况),同时参考本篇文章中给出的原理以及调优建议,合理地设置上述参数。

资源参数参考示例

以下是一份spark-submit命令的示例,大家可以参考一下,并根据自己的实际情况进行调节:

./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 \

资源参数调优实战篇

1. 几个主要参数参考配置(和上面稍微有出入,毕竟上面是引用美团16年的调优策略):
--num-executors:50~100
--driver-memory:1G~5G
--executor-memory:6G~10G
--executor-cores:3
--conf spark.default.parallelism:500~1000
2. 现有集群资源

420个核,2.7T内存

3. 分配策略

集群最常用的是三个人,我自己占了大头,那么我就按照占用集群资源1/2来设置自己的资源

--executor-cores:3
--num-executors:420/2/3 = 70 (总核/2/每个Executor的CUP cores数据量,这里我设的3个)
--driver-memory:4G (根据是否有collect算子进行设置)
--executor-memory:2.7T*1024/2/70 = 20G (总内存/2/num-executor)
--conf spark.default.parallelism=630 :(num-executors * executor-cores * 3 = 70 * 3 * 3 = 630)

每个参数都是通过集群资源、自己可用的资源计算出来的,最后我的提交脚本为:

./bin/spark-submit \--master yarn-cluster \--num-executors 70 \--executor-memory 20G \--executor-cores 3 \--driver-memory 4G \--conf spark.default.parallelism=630 \
4. 少配了两个参数?

参考美团给出的建议,我们发现我上面少配了两个参数:

--conf spark.storage.memoryFraction=0.5 \
--conf spark.shuffle.memoryFraction=0.3 \

我不配置的原因是:
上面这两个参数现在已经不推荐使用了,过时了,1.6之前可以使用,之后,由于默认是统一内存管理而不是静态内存管理,因此会提示:

Detected deprecated memory fraction settings: [spark.storage.memoryFraction, spark.shuffle.memoryFraction]. As of Spark 1.6,
execution and storage memory management are unified.
All memory fractions used in the old model are now deprecated and no longer read.
If you wish to use the old memory management,
you may explicitly enable `spark.memory.useLegacyMode` (not recommended).

后记

每个参数都是通过集群资源、自己可用的资源计算出来的,而不是随机给的

Spark集群资源如何分配相关推荐

  1. Spark详解(六):Spark集群资源调度算法原理

    1. 应用程序之间 在Standalone模式下,Master提供里资源管理调度功能.在调度过程中,Master先启动等待列表中应用程序的Driver,这个Driver尽可能分散在集群的Worker节 ...

  2. Spark 原理 —— 从 akka 到 spark 集群的启动

    1. actor 到 akka Actor 是一种消息并发模型,基于事件模型的并发机制. Scala 的 Actor 类似于 Java 中的多线程编程,不同在于: Scala 的 Actor 设计的初 ...

  3. Spark集群中HA环境搭建

    1.环境介绍 (1)操作系统ubuntu16.4.0 (2)两个节点:spark1(192.168.232.147),spark2(192.168.232.152) (生产环境下一般配置3台) (3) ...

  4. spark 并行处理_如何使用Spark集群并行处理大数据

    spark 并行处理 by Hari Santanam 通过Hari Santanam 如何使用Spark集群并行处理大数据 (How to use Spark clusters for parall ...

  5. Spark 集群模式概述

    Spark 集群模式概述 本文档简要概述了Spark如何在群集上运行,以使您更容易理解所涉及的组件.通读应用程序提交指南, 以了解有关在集群上启动应用程序的信息. 组件 Spark应用程序在群集上作为 ...

  6. 利用yarn capacity scheduler在EMR集群上实现大集群的多租户的集群资源隔离和quota限制...

    转自:https://m.aliyun.com/yunqi/articles/79700 背景 使用过hadoop的人基本都会考虑集群里面资源的调度和优先级的问题,假设你现在所在的公司有一个大hado ...

  7. 成功启动spark集群程序,使用多台电脑进行计算

    单独启动spark集群(不启动hadoop集群) start-spartk-all.sh spark-submit --class org.apache.spark.examples.JavaSpar ...

  8. 使用Docker安装Spark集群(带有HDFS)

    本实验在CentOS 7中完成 第一部分:安装Docker 这一部分是安装Docker,如果机器中已经安装过Docker,可以直接跳过 [root@VM-48-22-centos ~]# system ...

  9. spark集群详细搭建过程及遇到的问题解决(三)

    上篇文章中讲完了如何配置免密码登录的问题,现在讲述下,三个节点的环境配置过程. 所需要的hadoop-2.7.3.tar.gz . jdk-7u79-linux-x64.tar.gz . scala- ...

最新文章

  1. 为什么整数集合使用Z来表示?
  2. python3.6安装scrapy-Windows下安装scrapy(python3.6)
  3. Linux-wget/tar/ln 函数
  4. 阿里云短信isp.RAM_PERMISSION_DENY没有访问权限解决办法
  5. PostgreSQL 9.6.0 手册
  6. php无限分类下载,php无限分类
  7. Android:通过Intent传递对象、Parcelable
  8. 像excel一样规律填充(二)
  9. 非零矩阵A可以写成某个列满秩矩阵与某个行满秩矩阵的乘积
  10. PDF数字签名之(6.2如何生成公钥)
  11. 用计算机绘制工作表,《计算机操作基础Excel练习题答案.doc
  12. 用pdf转cad转换器进行操作的简单步骤
  13. 计算机考研作息时间表,2020考研的最佳作息时间表 如何安排学习时间
  14. 喜欢和平精英、王者荣耀的小伙伴,快来看看这些游戏模型都是怎么制作出来的
  15. 大二计算机学期总结报告,大二计算机的实训总结.docx
  16. 利用android monkey 抢支付宝红包
  17. HTML5:最后的火种
  18. 想比较全面地学习 SAP XXX,能指导下从哪儿开始学习吗?
  19. Python2.6-原理之类和oop(下)
  20. 关于Android Toast

热门文章

  1. 基于MODBUS-RTU协议的串口编程
  2. 洛谷P3413 SAC#1 - 萌数(数位dp)
  3. 浅谈企业内部安全漏洞的运营(一):规范化
  4. Havel-Hakimi定理 POJ1659
  5. 开发extjs常用的插件
  6. HttpClient4 TIME_WAIT和CLOSE_WAIT
  7. 解决多个py模块调用同一个python的logging模块,打印日志冲突问题
  8. Virtual Box创建共享目录
  9. ASA 防火墙 工作原理与配置实例
  10. Oracle技术之串行隔离对延迟段和INTERVAL分区的支持