首页 > 解决方案 > 优化 Spark 资源以避免内存和空间使用

问题描述

我有一个大约 190GB 的数据集,它被分成 1000 个分区。

我的 EMR 集群最多允许 10 个r5a.2xlargeTASK 节点和 2 个 CORE 节点。每个节点有 64GB 内存和 128GB EBS 存储。

在我的 spark 作业执行中,我已将其设置为使用executor-cores 5, driver cores 5, executor-memory 40g, driver-memory 50g, spark.yarn.executor.memoryOverhead=10g, spark.sql.shuffle.partitions=500,spark.dynamicAllocation.enabled=true

但我的工作一直因错误而失败,例如

spark.shuffle.MetadataFetchFailedException
spark.shuffle.FetchFailedException
java.io.IOException: No space left on device
Container Lost
etc...

我在网上找到的很多这类问题的答案都说会增加内存开销。我做到了,从 2G 到 10G。executor memory我的一共memoryOverhead是50G。40G 分配给执行者,10G 分配给开销。但我认为我已经达到了极限,因为我无法超过 56。

我认为我已尽一切可能优化我的 Spark 工作:

  1. 增加分区
  2. 增加 spark.sql.shuffle.partitions
  3. 增加执行器和开销内存

但我的工作仍然失败。还有什么我可以尝试的吗?我应该更多地增加我的开销,以便我的执行程序内存/开销内存为 50/50?我在 ganglia 工作的内存配置文件如下所示:

(急剧下降是当集群由于它们死亡而刷新所有执行程序节点时)

在此处输入图像描述

任何见解将不胜感激

谢谢你

编辑:[解决方案]

Debuggerrr由于基于他在回答中的建议,我将在我的帖子中附加了解决我的问题的确切解决方案。

[编辑 2]:专门为我的工作工作 的参数是:

--executor-cores 5 --driver-cores 5 --executor-memory 44g --driver-memory 44g --num-executors 9 --conf spark.default.parallelism=100 --conf spark.sql.shuffle.partitions=300 --conf spark.yarn.executor.memoryOverhead=11g --conf spark.shuffle.io.retryWait=180s --conf spark.network.timeout=800s --conf spark.serializer=org.apache.spark.serializer.KryoSerializer --conf spark.dynamicAllocation.enabled=false

标签: apache-sparkpysparkamazon-emr

解决方案


您可以尝试以下任一步骤:

  1. Memory overhead应该是10%Executor 内存或328 MB. 不要将其增加到任何值。
  2. 删除驱动程序核心。
  3. 如果您有 10 个节点,则指定number of executors. 您必须以为 YARN 和后台进程留出一些空间的方式计算它。此外,您可以尝试增加 1 或 2 个内核。
  4. 在一个模式下运行它cluster,无论您分配给执行器的数量是多少,都为其添加 +1,因为在集群模式下 1 个执行器将被视为驱动程序执行器。
  5. 此外,最后一件事就是您为提交/处理该 190GB 文件而编写的代码。浏览您的代码并找到优化它的方法。寻找收集方法,或不必要地使用连接、合并/重新分区。如果不需要的话,找一些替代品。
  6. 对您在代码中经常使用的数据帧使用持久(仅限内存和磁盘)选项。
  7. 此外,我尝试的最后一件事是手动执行这些步骤spark-shell on EMR,您将知道代码的哪一部分需要花费很多时间来运行。

您也可以参考这个官方博客以获取一些提示。


推荐阅读