优化Spark资源,避免内存和空间占用

问题描述 投票:0回答:2

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

我的 EMR 集群最多允许 10 个

r5a.2xlarge
TASK 节点和 2 个 CORE 节点。每个节点有 64GB mem 和 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? 我的工作的神经节的内存概况看起来像这样:

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

任何见解将不胜感激

谢谢你

编辑:[解决方案]

我在我的帖子中附加了解决我问题的确切解决方案,这要归功于

Debuggerrr
基于他在答案中的建议。

  • 我有一个大数据框,在做了很多之后我正在重复使用它 对其他数据帧的计算。通过使用
    persist()
    方法 (由 Debuggerrr 建议),我能够将其保存到内存和光盘中 并简单地回调它,而不需要清理它的一部分 GC.
  • 我还遵循了最佳实践博客 Debuggerrr 在他的回答中提到的并计算了正确的执行器内存、执行器数量等。但我失败的是禁用
    spark.dynamicAllocation.enabled
    。该博客指出,如果我们手动计算资源,最好将该属性设置为 false,因为如果您的计算与其不一致,spark 往往会错误分配资源。一旦我将其设置为 false,并设置正确的执行器和火花属性,它就像一个魅力!

[编辑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-spark pyspark amazon-emr
2个回答
4
投票
您可以尝试以下任一步骤:

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

官方博客了解一些技巧。


0
投票
看来您对spark进行了很多研究。 您能帮我解决这个问题吗:

从 Spark 2.4.5 迁移到 Spark 3.2.0 后的问题

谢谢

© www.soinside.com 2019 - 2024. All rights reserved.