version:2.4.0-cdh6.3.0
文章目录
spark properties
常用配置
配置属性的2种方式:
- 通过SparkConf对象在程序内设置
- 通过spark- submit --conf/-c 在程序提交时设置,此外spark-submit还会读取conf/spark-defaults.conf中的属性
对于未设置的属性,spark会使用默认值。
spark属性大致可以分为两类:
- 和部署(deploy)相关的,这一类需要在配置文件中或spark-submit时设置。在程序内设置可能会无法生效,这取决于部署模式和集群管理器的选择
- 和运行(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)
spark architecture
引用自https://spark.apache.org/docs/2.4.0/cluster-overview.html
cluster manager支持以下几种模式
- standalone
- Apache Mesos
- hadoop yarn
- kubernetes
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.youkuaiyun.com/wisgood/article/details/51436060
spark 1.5版本之前的内存管理模式,将heap space严格划分成固定大小的区域,如果没有对应用进行调优,估计会经常出现内存溢出问题。
在spark 2.4.0时默认关闭,通过设置spark.memory.useLegacyMode=true可以启用,默认是false。
虽然是早期的内存管理模式,但是可以借助它理解spark的内存管理、内存分配模式。
spark on yarn
引用自https://www.cnblogs.com/yangsy0915/p/5118100.html
引用自:https://www.cnblogs.com/zz-ksw/p/11403622.html
容器内存由: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官方文档
https://blog.youkuaiyun.com/zc19921215/article/details/103464648
driver端、executor端
driver端有一个,在driver端上运行Application的main()函数,并创建SparkContext,spark通过SparkContext与ClusterManager通信,进行资源的申请,任务的分配、监控等。
executor端有多个,负责具体任务的执行
当所有executor端任务执行完毕,driver端负责将SparkContext关闭
https://blog.youkuaiyun.com/liweihope/article/details/91349902
spark submit
格式
./bin/spark-submit \
--class <main-class> \
--master <master-url> \
--deploy-mode <deploy-mode> \
--conf <key>=<value> \
... # other options
<application-jar> \
[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简要说明