原文地址: http://blog.javachen.com/2015/06/09/memory-in-Spark-on-yarn.html
本文主要了解Spark On YARN部署模式下的内存分配情况,因为没有深入研究Spark的源代码,所以只能根据日志去看相关的源代码,从而了解“为什么会这样,为什么会那样”。
说明
按照Spark应用程序中的driver分布方式不同,Spark on YARN有两种模式: yarn-client模式、yarn-cluster模式。
当在YARN上运行Spark作业,每个Spark executor作为一个YARN容器运行。Spark可以使得多个Tasks在同一个容器里面运行。
下图是yarn-cluster模式的作业执行图,图片来源于网络:
关于Spark On YARN相关的配置参数,请参考Spark配置参数。本文主要讨论内存分配情况,所以只需要关注以下几个内心相关的参数:
- spark.driver.memory:默认值512m
- spark.executor.memory:默认值512m
- spark.yarn.am.memory:默认值512m
- spark.yarn.executor.memoryOverhead:值为executorMemory * 0.07, with minimum of 384
- spark.yarn.driver.memoryOverhead:值为driverMemory * 0.07, with minimum of 384
- spark.yarn.am.memoryOverhead:值为AM memory * 0.07, 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.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
总结
在client模式下,AM对应的Container内存由spark.yarn.am.memory加上spark.yarn.am.memoryOverhead来确定,executor加上spark.yarn.executor.memoryOverhead的值之后确定对应Container需要申请的内存大小,driver和executor的内存加上spark.yarn.driver.memoryOverheadspark.yarn.executor.memoryOverhead的值之后再乘以0.54确定storage memory内存大小。在YARN中,Container申请的内存大小必须为yarn.scheduler.minimum-allocation-mb的整数倍。
下面这张图展示了Spark on YARN 内存结构,图片来自How-to: Tune Your Apache Spark Jobs (Part 2):
至于cluster模式下的分析,请参考上面的过程。希望这篇文章对你有所帮助!