[CDH] Spark 属性、内存、CPU相关知识梳理

version:2.4.0-cdh6.3.0

文章目录

    • spark properties
      • 常用配置
        • spark task
        • spark task 使用的cpu核数
    • spark architecture
      • spark memory
      • spark on yarn
      • 问题1:什么情况下使用spark.executor.memoryOverhead
      • 问题2:什么情况下使用spark.executor.memory
      • 小总结:归根结底,spark中的cpu核数和内存的比例是多少时最合适???
      • driver端、executor端
    • spark submit

spark properties

常用配置

配置属性的2种方式:

  1. 通过SparkConf对象在程序内设置
  2. 通过spark- submit --conf/-c 在程序提交时设置,此外spark-submit还会读取conf/spark-defaults.conf中的属性

对于未设置的属性,spark会使用默认值。

spark属性大致可以分为两类:

  1. 和部署(deploy)相关的,这一类需要在配置文件中或spark-submit时设置。在程序内设置可能会无法生效,这取决于部署模式和集群管理器的选择
  2. 和运行(runtime control)相关的,可以选择任意方式进行设置

文档中提及的属性清单
https://spark.apache.org/docs/latest/configuration.html

大多数默认值是合理、有效、可以通用的,但以下几项需要依据集群配置、提交作业的大小进行额外的设置

spark 和内存、cpu相关的属性及其默认值

属性 默认值 说明
spark.driver.memory 1G
spark.driver.memoryOverhead driverMemory * 0.10, with minimum of 384
spark.executor.memory 1G
spark.executor.memoryOverhead executorMemory * 0.10, with minimum of 384|
spark.driver.cores 1
spark.executor.cores yarn模式下默认是1
属性 说明
spark.executor.instances 60 定义作业所需的容器(executor)数量N,能有多少取决于集群内可以分配给容器的总的内存M和总的cpu核数C,
spark.executor.memory= x 1 x_1 x1,
spark.executor.cores= x 2 x_2 x2,
N = m i n ( M / x 1 , C / x 2 ) N=min(M/x_1,C/x_2) N=min(M/x1,C/x2)
主要取决于你准备给一个容器分配几G内存,然后准备给容器分配多少个CPU内核,或者反着来推算
spark.executor.memory 3G 为容器分配的内存大小
spark.executor.cores 2 为容器分配的cpu核数,如果集群cpu有空闲可以增加
spark.executor.memoryOverhead 1G 设置容器内堆外内存的大小
spark task
spark task 使用的cpu核数

常看到文章中说分配给容器的cpu核数会影响容器内task的数量
在spark的代码中可以看到如下的配置属性,默认值为1

private[spark] val CPUS_PER_TASK = ConfigBuilder("spark.task.cpus").intConf.createWithDefault(1)

[CDH] Spark 属性、内存、CPU相关知识梳理_第1张图片
在这里插入图片描述

spark architecture

引用自https://spark.apache.org/docs/2.4.0/cluster-overview.html

[CDH] Spark 属性、内存、CPU相关知识梳理_第2张图片
cluster manager支持以下几种模式

  1. standalone
  2. Apache Mesos
  3. hadoop yarn
  4. kubernetes

[CDH] Spark 属性、内存、CPU相关知识梳理_第3张图片

spark memory

之所以关注内存的问题,主要是为了应对应用中可能出现的OOM问题
spark中的OOM大致有两类driver端OOM和executor端OOM

例如:

ExecutorLostFailure (executor 710 exited caused by one of the running tasks) Reason: 
Container killed by YARN for exceeding memory limits. 1.5 GB of 1.5 GB physical memory used. Consider boosting 
spark.yarn.executor.memoryOverhead or disabling yarn.nodemanager.vmem-check-enabled because of YARN-4714.
yarn.nodemanager.resource.memory-mb //每个NodeManager可以供yarn调度(分配给container)的物理内存,单位MB
yarn.nodemanager.resource.cpu-vcores  //每个NodeManager可以供yarn调度(分配给container)的vcore个数
 
yarn.scheduler.maximum-allocation-mb //每个container能够申请到的最大内存
yarn.scheduler.minimum-allocation-mb //每个container能够申请到的最小内存,如果设置的值比该值小,默认就是该值
yarn.scheduler.increment-allocation-mb //container内存不够用时一次性加多少内存 单位MB。CDH默认512M
yarn.scheduler.minimum-allocation-vcores //每个container能够申请到的最小vcore个数,如果设置的值比该值小,默认就是该值
yarn.scheduler.maximum-allocation-vcores //每个container能够申请到的最大vcore个数。
 
yarn.nodemanager.pmem-check-enabled //是否对contanier实施物理内存限制,会通过一个线程去监控container内存使用情况,超过了container的内存限制以后,就会被kill掉。
yarn.nodemanager.vmem-check-enabled //是否对container实施虚拟内存限制

引用自:https://blog.csdn.net/wisgood/article/details/51436060

spark 1.5版本之前的内存管理模式,将heap space严格划分成固定大小的区域,如果没有对应用进行调优,估计会经常出现内存溢出问题。

在spark 2.4.0时默认关闭,通过设置spark.memory.useLegacyMode=true可以启用,默认是false。

虽然是早期的内存管理模式,但是可以借助它理解spark的内存管理、内存分配模式。
[CDH] Spark 属性、内存、CPU相关知识梳理_第4张图片

spark on yarn

引用自https://www.cnblogs.com/yangsy0915/p/5118100.html

[CDH] Spark 属性、内存、CPU相关知识梳理_第5张图片

引用自:https://www.cnblogs.com/zz-ksw/p/11403622.html

[CDH] Spark 属性、内存、CPU相关知识梳理_第6张图片

[CDH] Spark 属性、内存、CPU相关知识梳理_第7张图片
容器内存由:spark.executor.memory、spark.executor.memoryOverhead两大部分组成

spark.executor.memory中又划分出spark.shuffle.memoryFraction和

在官方文档中可以看到2.4.0版本中这个属性已弃用,当spark.memory.useLegacyMode=true时这个配置属性会读取这个属性
在这里插入图片描述
数据在shuffle时,如果内存中的数据大小超出这个限制,内存中的数据会溢出到磁盘中。如果经常发生溢出(spill),可以考虑增加spark.storage.memoryFraction来减少数据溢出。

问题1:什么情况下使用spark.executor.memoryOverhead

说明:每个executor分配的堆外内存数量,除非另有说明,否则这一部分作为内存使用,主要当作虚拟内存、内部字符存储、其它本机开销。这部分内存的大小随着spark.executor.memory的增大而增大,通常是6%-10%,这个属相在yarn、kubernets模式下支持

计算公式:max(executorMemory*0.10,384)
取值范围:[384, + ∞ +\infty + )
单位:MB

问题2:什么情况下使用spark.executor.memory

容器内的task共享spark.executor.memory,task运行时使用这一部分的内存,也就是说当spark.executor.memory不足时,会占用spark.executor.memoryOverhead ,当加上spark.executor.memoryOverhead也不够时,会一次性增加yarn.scheduler.increment-allocation-mb大小的内存默认是512M

到这里,总算明白为什么报错信息会让你调整spark.yarn.executor.memoryOverhead的大小,但是这不是根本原因,根本原因是spark.executor.memory设置的太小了!!!!。

在yarn模式下,容器内存不足时会一次性增加yarn.scheduler.increment-allocation-mb大小的内存默认是512M,如果还是不够,就会被yarn kill掉,也就出现了下面的报错

ExecutorLostFailure (executor 710 exited caused by one of the running tasks) Reason:
Container killed by YARN for exceeding memory limits. 1.5 GB of 1.5 GB physical memory used. Consider boosting
spark.yarn.executor.memoryOverhead or disabling yarn.nodemanager.vmem-check-enabled because of YARN-4714.

小总结:归根结底,spark中的cpu核数和内存的比例是多少时最合适???

这个需要尝试不同的组合,个人认为内存一定要管够,否则任务挂掉了就直接没了,cpu给的少也只是跑的慢一些。

task是spark的最小作业单元

毫无疑问,task跑的越安全、越快,失败次数越少,应用执行的就越快越稳,其它都是次要的!!!

回到上面的异常中去,解决措施如下:
一倍一倍的进行调整
增大spark.executor.memory

减少spark.executor.cores

目的是让容器中的每个task得到比之前更多的内存

默认配置下spark.executor.memory和spark.executor.cores的比例是1:1
可以试试2:1、3:1、4:1等等

参考资料:
Spark官方文档

Spark中的内存开销问题

https://blog.csdn.net/zc19921215/article/details/103464648

Spark on Yarn 架构解析

CDH Yarn 调度资源指南 - CDH6.0.x 详解

Spark 内存架构

driver端、executor端

driver端有一个,在driver端上运行Application的main()函数,并创建SparkContext,spark通过SparkContext与ClusterManager通信,进行资源的申请,任务的分配、监控等。

executor端有多个,负责具体任务的执行

当所有executor端任务执行完毕,driver端负责将SparkContext关闭

https://blog.csdn.net/liweihope/article/details/91349902
[CDH] Spark 属性、内存、CPU相关知识梳理_第8张图片

spark submit

格式

./bin/spark-submit \
  --class  \
  --master  \
  --deploy-mode  \
  --conf = \
  ... # other options
   \
  [application-arguments]
--class 应用程序的入口
--master 集群的主URL
--deploy-mode 部署方式
--conf 配置属性
application-jar 应用程序的依赖jar包路径
application-arguments 传递给主类的 main 方法的参数
# Run on a Mesos cluster in cluster deploy mode with supervise
./bin/spark-submit \
  --class org.apache.spark.examples.SparkPi \
  --master mesos://207.184.161.138:7077 \
  --deploy-mode cluster \
  --supervise \
  --executor-memory 20G \
  --total-executor-cores 100 \
  http://path/to/examples.jar \
  1000

最后的100是传递给org.apache.spark.examples.SparkPi的参数(传递给main函数的参数)

参考资料:
spark-submit简要说明

你可能感兴趣的:(Spark,spark,scala,big,data)