Spark内存模型及常见的优化方式
参考:https://www.cnblogs.com/coco2015/p/11240677.html
1.简介
Spark执行器Executor的内存管理是建立在JVM的内存管理之上,并对JVM的空间进行了更为详细的分配,此外,Spark还引入了独立于JVM托管的Heap之外利用c-style的malloc从os分配到的memory.(因为,这部分内存不再由JVM托管,可以避免JVM object overhead和垃圾回收的开销)。总的来说,spark的内存包含JVM(OnHeap和OffHeap)和Off-Heap两种。
- JVM OnHeap:大小由”--executor-memory”(即 spark.executor.memory)参数指定。Executor中运行的并发任务共享JVM堆内内存。
- JVM OffHeap:大小由”spark.yarn.executor.memoryOverhead”参数指定,主要用于JVM自身,字符串, NIO Buffer等开销。
- Off-heap模式:默认情况下Off-heap模式的内存并不启用,可以通过”spark.memory.offHeap.enabled”参数开启,并由spark.memory.offHeap.size指定堆外内存的大小(占用的空间划归JVM OffHeap内存)
接下来介绍的主要是yarn模式下,非off-heap模式(即只介绍JVM模式的Executor内存管理的情形,且Off-Heap均指代为JVM下的Off-Heap
2.Executor内存划分

(摘自网上)
如上图所示,Yarn集群管理中,Spark 以Executor Container的形式在NodeManager中运行,其可使用的内存上限由“yarn.scheduler.maximum-allocation-mb” 指定, 称其为MonitorMemory。对现有Yarn集群,存在:ExecutorMemory + MemoryOverhead <= MonitorMemory,若应用提交之时,指定的 ExecutorMemory与MemoryOverhead 之和大于 MonitorMemory,则会导致Executor申请失败;若运行过程中,实际使用内存超过上限阈值,Executor进程会被Yarn终止掉(kill)。
"spark.executor.memory"指定的内存为JVM最大分配的堆内存("-xmx"),Spark为了更高效的使用这部分内存,对这部分内存进行了细分,对基于spark2(1.6+)对堆内存分配比例进行了描述:

其中:
- Reserved Memory 保留内存,系统默认值为300,一般无需改动,不用关心此部分内存。 但如果Executor分配的内存小于 1.5 * 300 = 450M时,Executor将无法执行。
- Storage Memory 存储内存,用于存放广播数据及RDD缓存数据。由上图可知,Spark 2+中,初始状态下,Storage及Execution Memory均约占系统总内存的30%(1 * 0.6 * 0.5 = 0.3)。在UnifiedMemory管理中,这两部分内存可以相互借用,为了方便描述,我们使用storageRegionSize来表示“spark.storage.storageFraction”。当计算内存不足时,可以改造storageRegionSize中未使用部分,且StorageMemory需要存储内存时也不可被抢占; 若实际StorageMemory使用量超过storageRegionSize,那么当计算内存不足时,可以改造(StorageMemory – storageRegionSize)部分,而storageRegionSize部分不可被抢占。

浙公网安备 33010602011771号