设为首页 加入收藏

TOP

(八)Spark学习笔记之资源分配
2019-04-20 13:21:28 】 浏览:112
Tags:Spark 学习 笔记 资源分配

应用程序内存和CPU分配

local模式 — 不需要安装 spark,也不需要启动 spark 集群
standalone模式 — 需要安装 spark,需要启动 spark 集群。
yarn模式 — 需要安装 spark,但不需要启动 spark 进群。

在 spark-default.conf 文件中设置 spar k的资源配置,资源分配参数为 spark.xxx;如 spark.driver.cores。

有三种方式设置 spark 的配置属性,其优先级从高到低。

  1. 在程序代码中通过 sparkConf 对象设置;
  2. 通过 spark-submit 任务提交工具设置;
  3. 通过 spark-default.conf 文件配置。

优先级:Spark-default.conf < spark-submit –conf < SparkConf代码
在这里插入图片描述

spark-submit --master spark://bigdata01:7077 
--conf spark.executor.memory=1201m 
--conf spark.executor.cores=1 
--class sparkcore.learnTextFile /opt/sparkapp/learnTextFileCode.jar

spark .executor.memory 8G
spark.driver.memory 16G
spark.driver.maxResultSize 8G
spark.akka.frameSize 512

如在 spark-env.sh 中:
在这里插入图片描述
从 webUI 上可以看出,每个 worker 节点都启动了两个 executor,一个 core 核心和 900m 内存。
在这里插入图片描述

应用程序的资源分配实战

如果在配置中设置 单个 executor 的 cores 数量超过了可申请 cores 的数量,程序没法启动运行。

例如:

spark-submit --master spark://bigdata01:7077 
--executor-memory 900m 
--executor-cores 6 
--class sparkcore.learnTextFile /opt/sparkapp/learnTextFile.jar

在这里插入图片描述
如果 worker 有足够的资源,对于同一个应用,会在每个 worker 节点上启动多个 executor。

spark-submit --master spark://bigdata01:7077 
--executor-memory 918m 
--executor-cores 1 
--class sparkcore.learnTextFile /opt/sparkapp/learnTextFile.jar

在这里插入图片描述
在这里插入图片描述

另一种参数赋值的方式 --conf PROP=VALUE

spark-submit --master spark://bigdata01:7077 
--conf spark.executor.memory=1201m 
--conf spark.executor.cores=1 
--class sparkcore.learnTextFile /opt/sparkapp/learnTextFile.jar

常见配置项

Spark 常用配置项,主要是对 Spark 运行过程中各个使用资源的地方,通过调整参数值,优化资源使用效率,提升 Spark 作业性能。

num-executors
在这里插入图片描述
该参数用于设置 Spark 作业需要使用多少个 Executor 进程来执行。Driver 向 Yarn 集群管理器申请资源时,Yarn 集群管理器会尽可能按照设置参数来在集群的各个 worker 节点上,启动相应数量的 Executor 进程。默认参数只会提供少量的 Executor 进程,此时 Spark 作业的运行速度是非常慢的。

该参数设置的太少,将无法充分利用集群资源;如果参数设置太多,大部分队列可能无法给与充分的资源。

executor-memory(spark.executor.memory)

该参数用于设置每个 Executor 进程的内存。Executor 内存的大小,很多时候直接决定了 Spark 作业的性能,而且跟常见的额 JVM OOM 异常,也有直接关系。

每个 Executor 进程的内存设置 4G ~ 8G 较为合适。但是这只是一个参考值,具体的设置还需要根据不同部门的资源队列来决定。如果有其他部门方向该内存资源,那么建议申请的内存大小最好不要超过总内存资源的 1/3 ~ 1/2,避免自己的 Spark 作业占用所有资源而导致其他作业无法运行。

executor-cores(spark.executor.cores)
该参数用于设置每个 Executor 进程的 CPU core 数量。这个参数决定了每个 Executor 进程并行执行 task 线程的能力。因为每个 CPU core 同一时间只能执行一个task线程,因此每个 Executor 进程的 CPU core 数量越多,越能快速地执行完分配给自己的所有 task 线程。

Executor 的CPU core 数量设置为 2~3 个比较合适,但是也必须根据不同部门的资源队列来决定。
如果与其他部门共享这个资源,那么建议申请的CPU core不能超过总CPU cores的 1/3 ~ 1/2左右,这样可以避免影响其他作业的运行。

driver-memory
该参数用于设置 driver 进程的内存。

Driver 的内存通常不需要设置,或者设置 1G 左右。但是如果需要设置 collect 算子将 RDD 的数据全部拉去到 Driver上进行处理,那么必须确保 Driver 的内存足够大,否则将出现 OOM 内存溢出的问题。

spark.defaultparallelism
该参数用于设置每个 stage 的默认 task 数量。

建议:spark 作业的默认 task 的数量为 500 ~ 1000 个较为合适。如果不设置这个参数,那么此时就会导致 spark 自己根据底层 HDFS 的 block 数量来设置 task 数量,默认是一个HDFS block 对应一个 task。通常来说,spark 默认设置的数量偏少的。如果 taks 数量偏少,就会导致 executor 没法提升性能。

例如:如果 task 只有一个或者几个,那么 90% 的 executor 进程可能根本没有 task 执行,只能浪费资源。

因此,建议该值设置为:num-executors * executor-cores 的 2~3 倍较为合适。

spark.storage.memoryFraction
在这里插入图片描述
该参数用于设置 RDD 持久化数据在 executor 内存中所占的比例,默认是 0.6。即 executor 中 60% 的内存用来保存持久化的 RDD 数据。

在 spark 作业中,如果有较多的 RDD 持久化操作,那么该值可以考虑提高些。也就是说提高 RDD 持久化所占内存的比例,保证持久化数据能够被容纳在内存中,避免内存不足的情况下缓存更多的数据到磁盘,降低性能能。

但是如果 spark 作业要进行比较多的 shuffle 操作,而持久化的操作比较少,那么这个参数值可以降低点,让 shuffle 操作所占用的内存提高,而 RDD 持久化的内存减少。
当在作业中频繁的出现 GC 操作,那么表示进行算子操作的内存是比较不够用的,那么需要降低该值。

spark.shuffle.memoryFraction
在这里插入图片描述
该参数用于设置 shuffle 操作中能过使用的 executor 内存的比例,默认是0.2。也就是说:executor 会默认分配 20% 的内存用于进行 shuffle 算子的操作。shuffle 操作在进行聚合时,如果发现使用的内存超过了 20% 的限制,那么多余的数据将会溢写到磁盘文件中。此时将会降低性能。

如果 spark 作业中的 RDD 持久化操作比较少,且 shuffle 操作比较多时,建议降低持久化操作 spark.storage.memoryFraction 的内存所占的比例,提高 shuffle 操作的内存所占的比例,避免 shuffle 过程中数据过多时内存不够用,溢写到磁盘,降低性能。
如果频繁的 GC 导致运行缓慢,意味着 task 执行用户代码的内存不够用,那么这个参数值依旧需要降低。

注:如果发生频繁的 GC,是因为 JVM 不够用了,因为 executor 就是运行在 JVM 中,那么就需要保证 JVM 的内存不被完全使用,因此需要降低 spark.storage.memoryFraction 或者 spark.shuffle.memoryFraction 的比例值。

而且还要知道 executor-memory 是系统分配个 executor 的内存大小,其值由 spark.storage.memoryFraction 和 spark.shuffle.memoryFraction,以及其它保留等所共同决定的。

在 standalone 模式下,因为 executor 是进程级别,对应一个 JVM 的进程。task 是线程级别。而 worker 表示实体的节点设备。一个 worker 节点可以有多个 executor 进程,一个 executor 进程可以有多个 task 线程。同时一个 task 线程对应一个 CPU core。

资源参数的调优,没有固定的参数值。需要根据项目的实际情况进行设置。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇spark IDE:   System memory.. 下一篇Spark之   Spark Streaming..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目