EMR/EMR Serverless中Spark Executor内存分配仅为设定值一半的问题
Spark Executor内存仅为设置值一半的原因分析
核心原因:混淆堆总内存与可用计算/存储内存
你设置的spark.executor.memory=12G是Executor的JVM堆总内存,但Spark会按固定比例拆分堆内存:
- 60%(EMR默认
spark.memory.fraction=0.6)分配给存储+执行内存(用于缓存数据、Shuffle/Join计算); - 40%分配给用户内存(用于用户代码对象、元数据存储)。
如果你在Spark UI中看到的是存储/执行内存的可用值,12G总堆内存对应的可用计算/存储内存约为7.2G,扣除JVM元空间等少量额外占用后,就会接近你看到的6.7G;20G总堆内存对应的可用值约为12G,和你观察到的11G一致。这是Spark内存模型的正常行为,并非分配异常。
其他可能的次要因素
EMR默认堆外内存预留:
EMR会为Executor的JVM分配堆外内存(如元空间、直接内存),这部分内存从YARN容器总内存中扣除,但通常仅占用几百MB到1GB,不会导致内存减半。代码参数语法错误(潜在风险):
你的Airflow代码中spark.jars参数存在拼接错误:
"--conf spark.jars=configuration['S3_DAGS_HDFS_JARS_PATH']+"/hudi/hudi-utilities-bundle_*.jar" +
这里Python变量未正确嵌入字符串,会导致Spark无法识别Jar包路径,建议修正为:
f"--conf spark.jars={configuration['S3_DAGS_HDFS_JARS_PATH']}/hudi/hudi-utilities-bundle_*.jar" +
验证方式
- 打开Spark UI的Executors页面,查看
Memory列数值:如果显示为你设置的12G/20G,说明内存分配正常,你看到的是拆分后的可用内存; - 查看YARN Application Master页面,确认容器总内存是否为
spark.executor.memory + spark.executor.memoryOverhead(默认overhead为executor内存的10%)。
内容的提问来源于stack exchange,提问作者Roobal Jindal
相关产品推荐
相关产品推荐

