spark内存说明

单个executor内存:

SPARK_EXECUTOR_MEMORY+ spark.yarn.executor.memoryOverhead

内存说明:

1、ExecutorMemory为JVM进程的Java堆区域。大小通过属性spark.executor.memory设置。用于缓存RDD数据的memoryStore位于这一区域。 一个Executor用于存储RDD的空间=(ExecutorMemory– MEMORY_USED_BY_RUNTIME) * spark.storage.memoryFraction *spark.storage.safetyFraction 参数说明:
spark.storage.memoryFraction该参数用于设置RDD持久化数据在Executor内存中能占的比例,默认是0.6。也就是说,默认Executor 60%的内存,可以用来保存持久化的RDD数据。
spark.storage.safetyFraction:Spark1.5.1进程的默认堆空间是1g,为了安全考虑同时避免OOM,Spark只允许利用90%的堆空间,spark中使用spark.storage.safetyFraction用来配置该值(默认是0.9).
(spark.shuffle.memoryFraction该参数用于设置shuffle过程中一个task拉取到上个stage的task的输出后,进行聚合操作时能够使用的Executor内存的比例,默认是0.2。)

2.MemoryOverhead是JVM进程中除Java堆以外占用的空间大小,包括方法区(永久代)、Java虚拟机栈、本地方法栈、JVM进程本身所用的内存、直接内存(Direct Memory)等。 通过spark.yarn.executor.memoryOverhead设置,单位MB。如果Java堆或者永久代的内存不足,则会产生各种OOM异常,executor会被结束。 在Java堆以外的JVM进程内存占用较多的情况下,应该将MemoryOverhead设置为一个足够大的值,以防JVM进程因实际占用的内存超标而被kill。
当在YARN上运行Spark作业,每个Spark executor作为一个YARN容器运行。Spark可以使得多个Tasks在同一个容器里面运行。 同样,实际运行过程中ExecutorMemory+MemoryOverhead之和(JVM进程总内存)超过container的容量。YARN会直接杀死container。


Overhead大小

Executor端:由spark.yarn.executor.memoryOverhead设置,spark1.5.1默认值executorMemory * 0.10与384的最大值。
Driver端:由spark.yarn.driver.memoryOverhead设置,spark1.5.1默认值driverMemory * 0.10与384的最大值。


注意:

  • --executor-memory/spark.executor.memory 控制 executor 的堆的大小,但是 JVM 本身也会占用一定的堆空间,比如内部的 String 或者直接 byte buffer, spark.yarn.XXX.memoryOverhead 属性决定向 YARN 请求的每个 executor 或dirver或am 的额外堆内存大小,默认值为 max(384, 0.07 * spark.executor.memory )
  • 在 executor 执行的时候配置过大的 memory 经常会导致过长的GC延时,64G是推荐的一个 executor 内存大小的上限。
  • HDFS client 在大量并发线程时存在性能问题。大概的估计是每个 executor 中最多5个并行的 task 就可以占满写入带宽。

另外,因为任务是提交到YARN上运行的,所以YARN中有几个关键参数,参考YARN的内存和CPU配置:

  • yarn.app.mapreduce.am.resource.mb :AM能够申请的最大内存,默认值为1536MB
  • yarn.nodemanager.resource.memory-mb :nodemanager能够申请的最大内存,默认值为8192MB
  • yarn.scheduler.minimum-allocation-mb :调度时一个container能够申请的最小资源,默认值为1024MB
  • yarn.scheduler.maximum-allocation-mb :调度时一个container能够申请的最大资源,默认值为8192MB

发表评论