上一篇:二、Spark算子调优最佳实践
?1、内存的具体配置及原因
YARN Container里面实际的内存结构,即yarn-cluster模式下Executor内存使用的实现方式,如下图:
?yarn.nodemanager.resource.memory-mb控制在每个节点上Container能够使用的最大内存。可以使用spark.executor.memory来配置每个Executor使用的内存总量。比如:
--executor-memory 8G
Executor可使用的内存中,主要分为以下三块:
- 第一块让task执行用户编写的代码使用,默认占executor总内存的20%
- 第二块让task通过shuffle过程拉取上一个stage的task的输出后,进行聚合等操作使用,默认也是占executor内存总大小的20%,用spark.shuffle.memoryFraction可配置比例。
- 第三块是让RDD cache使用,默认占executor总内存大小的60%,用spark.storage.memoryFraction可配置比例。官方建议这个比值不要超过JVM Old Gen区域的比值。因为RDD cache的数据通常长期驻留内存,理论上最终会被转移到Old Gen区域,如果数据量过大,势必会占满Old Gen区域,造成频繁的Full GC。如果频繁发生Full GC,那么可以适当调低这个值,腾出更多的空间用于执行任务;如果有过多的minor GC,而不是Full GC,那么可以为Eden区域分配更大的内存。如果Eden大小为E,那么可以设置-Xmn=4/3*E(调整到4/3是考虑到survivor区域所需的空间)。
还有一个重要的参数,即spark.yarn.executor.memoryOverhead,系统分配可选的堆外内存。默认值为spark.executor.memory*0.7及384MB的最大值。
2、每个Executor的CPU的具体配置
--num-executors 6
集群上启动的executor的数量。
--executor-cores 2
?2是每个executor运行的核数,即executor能最大运行的并行task(任务)数。executor的每个核executor分配到的总内存。
3、并行度的设置
并行度是spark作业中,各个stage的task数量,也就代表了spark作业在各个阶段的并行度。官方建议,把task数量设置成spark app的总cpu核数的2~3倍,比如有100个core,那么合理的task数量应该在200~300。
val conf = new SparkConf()
conf.set("spark.default.parallelism", "200")
|