Spark 2.2 内存占用计算公式

在Spark内存管理调优中,我们需要重点关注的有两类内存:ExecutionMemory and storageMemory。ExecutionMemory用于spark计算中的shuffles、 joins、sorts 、 aggregations这些操作,storageMemory用于缓存数据和保存广播变量数据 。

下面参数均已spark2.2为准,不同版本会有些差异

一、Spark 内存管理
(1)spark内存管理源码入口:SparkEnv.scala,代码片段如下
val useLegacyMemoryManager = conf.getBoolean( "spark.memory.useLegacyMode" , false )
val memoryManager: MemoryManager =
if (useLegacyMemoryManager) {
new StaticMemoryManager(conf, numUsableCores)
} else {
UnifiedMemoryManager (conf, numUsableCores)
}
通过源码可知,现在的spark内存管理有两种:静态内存管理 StaticMemoryManager和统一内存管理 UnifiedMemoryManager, 通过参数 spark.memory.useLegacyMode 控制


(2)静态内存管理内存计算公式(源码见StaticMemoryManager.scala):
ExecutionMemory =  systemMemory * spark.shuffle.memoryFraction* spark.shuffle.safetyFraction= executor-memory*0.2*0.8
storageMemory =  systemMemory* spark.storage.memoryFraction* spark.storage.safetyFraction = executor-memory*0.6*0.9


(3)统一内存管理内存计算公式(源码见 UnifiedMemoryManager.scala ):
预留内存reservedMemory=300M
假设spark 应用 分配的 executor内存为 systemMemory= 2G可(通过参数 --executor-memory 2g设置 ), systemMemory 实际值要比设置 executor-memory 的稍小
ExecutionMemory + storageMemory ) = ( systemMemory- reservedMemory) spark.memory.fraction =(2048-300)*0.6=1048.8M (实际会比该值稍小)
storageMemory = ( systemMemory- reservedMemory) spark.memory.fraction *  spark.memory.storageFraction =(2048-300)*0.6*0.5=524.4M
Spark 2.2 内存占用计算公式_第1张图片

二、spark on yarn内存分配

(1) 相关参数介绍

参考博文: http://blog.javachen.com/2015/06/09/memory-in-spark-on-yarn.html?utm_source=tuicool
yarn最小分配单位是 container
关于Spark On YARN相关的配置参数,请参考 Spark配置参数 。本文主要讨论内存分配情况,所以只需要关注以下几个内心相关的参数:
spark.driver.memory :默认值512m
spark.executor.memory :默认值512m
spark.yarn.am.memory :默认值512m
spark.yarn.executor.memoryOverhead :值为 executorMemory * 0.1, with minimum of 384
spark.yarn.driver.memoryOverhead :值为 driverMemory * 0.1, with minimum of 384
spark.yarn.am.memoryOverhead :值为 AM memory * 0.1, with minimum of 384
注意:
--executor-memory/spark.executor.memory  控制 executor 的堆的大小,但是 JVM 本身也会占用一定的堆空间,比如内部的 String 或者直接 byte buffer, spark.yarn.XXX.memoryOverhead 属性决定向 YARN 请求的每个 executor 或dirver或am 的额外堆内存大小,默认值为  max(384, 0.1 * spark.executor.memory )
在 executor 执行的时候配置过大的 memory 经常会导致过长的GC延时,64G是推荐的一个 executor 内存大小的上限。
HDFS client 在大量并发线程时存在性能问题。大概的估计是每个 executor 中最多5个并行的 task 就可以占满写入带宽。
另外,因为任务是提交到YARN上运行的,所以YARN中有几个关键参数,参考 YARN的内存和CPU配置
yarn.app.mapreduce.am.resource.mb :AM能够申请的最大内存,默认值为1024MB
yarn.nodemanager.resource.memory-mb :nodemanager能够申请的最大内存,默认值为8192MB
yarn.scheduler.minimum-allocation-mb :调度时一个container能够申请的最小资源,默认值为1024MB
     yarn.scheduler.maximum-allocation-mb :调度时一个container能够申请的最大资源,默认值为8192MB
            yarn.scheduler.increment-allocation-mb : container内存增量,每次增加申请的内存是该值的整数倍,默认值为1G

(2)spark on yarn内存计算公式:
1、spark on yarn申请的container数=num-executors+1  (AM会占用一个container,一个executor占用 一个container)

2、executor需要申请的总内存:total=executor-memory+max(executor-memory*0.1,384)

3、executor所在container实际申请的内存分两种情况:

(1) total <= yarn.scheduler.minimum-allocation-mb,则实际分配内存大小为yarn.scheduler.minimum-allocation-mb
(2)total > yarn.scheduler.minimum-allocation-mb,则实际分配内存大小为yarn.scheduler.minimum-allocation-mb+( total-yarn.scheduler.minimum-allocation-mb)取 yarn.scheduler.increment-allocation-mb的整数倍

假设:yarn.scheduler.minimum-allocation-mb=2G,yarn.scheduler.increment-allocation-mb=1G,--executor-memory 2G
executor所在container实际申请的内存=2G+1G=3G

AM所在executor实际申请内存=2G

所有总申请内存为5G

 
  

你可能感兴趣的:(Spark)