参考 :
https://blog.csdn.net/jhk9898/article/details/55101225?locationNum=2&fps=1 这个不错
https://blog.csdn.net/hammertank/article/details/48346285
https://blog.csdn.net/u013487548/article/details/80445055
https://blog.csdn.net/lingbo229/article/details/80914283
一个Executor对应一个JVM进程。
从Spark的角度看,Executor占用的内存分为两部分:ExecutorMemory和MemoryOverhead
一、ExecutorMemory
ExecutorMemory为JVM进程的Java堆区域。大小通过属性spark.executor.memory
设置。也可以在spark-submit命令时用参数--executor-memory
设置。
二、MemeoryOverhead
MemoryOverhead是JVM进程中除Java堆以外占用的空间大小,包括方法区(永久代)、Java虚拟机栈、本地方法栈、JVM进程本身所用的内存、直接内存(Direct Memory)等。通过spark.yarn.executor.memoryOverhead设置,单位MB。
三、Spark统一内存管理
从上图可知主要包含三个部分
3.1、Reserved Memory
这部分内存是预留给系统使用,是固定不变的。
3.2、User Memory
默认为(“Java Heap” – Reserved Memory ) * 0.25
。分配Spark Memory剩余的内存,用户可以根据需要使用。可以存储RDD transformations
需要的数据结构,例如, 重写spark aggregation
,使用mapPartition transformation
,通过hash table
来实现aggregation
,这样使用的就是User Memory。
3.3、Spark Memeory
包含Storage Memeory
和 Excution Memory
两部分,两个边界由spark.memory.storageFraction设定,默认为0.5。但是两部分可以动态变化,相互之间可以借用,如果一方使用完,可以向另一方借用。
Storage Memeory
是用于缓存rdd数据, 广播变量。Excution Memory
存储Spark task执行过程中需要的对象,例如,Shuffle中map端中间数据的存储,以及hash aggregation中的hash table。如果内存不足,该空间也容许spill到磁盘。
四、相关影响的参数
4.1、 yarn.scheduler.maximum-allocation-mb
这个参数表示每个container能够申请到的最大内存,一般是集群统一配置。Spark中的executor进程是跑在container中,所以container的最大内存会直接影响到executor的最大可用内存。当你设置一个比较大的内存时,日志中会报错,同时会打印这个参数的值。
所以executor的总内存 必须满足:
executorMem< yarn.scheduler.maximum-allocation-mb