我该如何解决 AWS Glue Spark 任务中的“java.lang.OutOfMemoryError: Java heap space”(java.lang.OutOfMemoryError:Java 堆空间)错误?

2 分钟阅读
0

我的 AWS Glue 任务失败,出现“Command failed with exit code 1”(命令失败,退出代码为 1)错误。Amazon CloudWatch Logs 显示 “java.lang.OutOfMemoryError: Java heap space”(java.lang.OutOfMemoryError:Java 堆空间)错误。

简短描述

“java.lang.OutOfMemoryError: Java heap space”(java.lang.OutOfMemoryError:Java 堆空间)错误表明驱动程序或执行程序已耗尽 JVM 内存。要确定是驱动程序还是执行程序导致 OOM,请参阅调试 OOM 异常和任务异常

注意: 以下解决方法仅适用于驱动程序 OOM 异常。

驱动程序 OOM 异常是由以下问题引起的:

  • AWS Glue Spark 任务从 Amazon Simple Storage Service(Amazon S3)读取大量小文件
  • 驱动程序密集型操作,例如 collect()、广播联接和共享变量

解决方法

解决由大量小文件引起的驱动程序 OOM 异常

要解决由带有 DynamicFrames 的大量小文件引起的驱动程序 OOM 异常,请使用以下一种或多种方法。

激活 useS3ListImplementation

列出文件时,AWS Glue 会在驱动程序内存列表中创建文件索引。当您将 useS3ListImplementation 设置为 True 时,AWS Glue 不会同时在内存中缓存所有文件的列表。相反,AWS Glue 会分批缓存该列表。这意味着驱动程序不太可能耗尽内存。

请参阅以下如何使用 from_catalog 激活 useS3ListImplementation 的示例:

datasource0 = glueContext.create_dynamic_frame.from_catalog(database = "database", table_name = "table", additional_options = {'useS3ListImplementation': True}, transformation_ctx = "datasource0")

请参阅以下使用 from_options 激活 useS3ListImplementation 的示例:

datasource0 = glueContext.create_dynamic_frame.from_options(connection_type="s3", connection_options = {"paths": ["s3://input_path"], "useS3ListImplementation":True,"recurse":True}, format="json")

useS3ListImplementation 功能是 Amazon S3 ListKeys 操作的实现。这会将大型结果集分成多个响应。将 useS3ListImplementation 与任务书签一起使用是一种最佳实践。

分组

Spark 应用程序使用不同的 Spark 任务处理每个小文件。这可能会导致 OOM,因为驱动程序会存储并跟踪位置和任务信息。激活分组功能时,任务会处理一组多个文件而不是单个文件。当您使用动态帧,并且 Amazon S3 数据集包含超过 50,000 个文件时,分组会自动启用。有关详细信息,请参阅在大型组中读取输入文件

使用下推谓词进行筛选

使用下推谓词减少 AWS Glue 任务读取的 Amazon S3 文件和 Amazon S3 分区的数量。这会在读取基础数据之前从 AWS Glue 表中删除不必要的分区。有关详细信息,请参阅使用下推谓词进行预筛选

驱动程序大量操作引起的驱动程序 OOM 异常

使用以下方法之一解决由驱动程序大量操作引起的驱动程序 OOM 异常。

注意驱动程序密集型操作

collect() 是一个 Spark 操作,它从 Worker 那里收集结果,然后将其作为单个对象返回给驱动程序。结果可能非常大,这会让驱动程序不堪重负。默认情况下,Spark 配置 spark.driver.maxResultSize 设置为 1 GB,有助于保护驱动程序,以免不堪重负。

因此,请限制此类操作,尽可能使用诸如 take()takeSample()isEmpty() 之类的操作。

另外,请注意,如果关系(表)大于驱动程序的可用内存,则 Spark 中的广播连接可能会导致 OOM 错误。在将关系广播给执行程序之前,它是在驱动程序节点上实现的。如果要广播多个表,或者关系太大,则驱动程序可能会出现内存不足的情况。使用 Spark 配置 spark.sql.autoBroadcastJoinThresholdSpark 联接提示控制这种情况。

定期销毁共享变量

请务必谨慎使用共享变量。当您不再需要共享变量时,请将其销毁,因为它们可能会导致 Spark 驱动程序 OOM 异常。共享变量有两种类型:广播变量和累加器。

  • 广播变量是只读数据,仅发送给执行程序一次。此类变量适合存储不可变的参考数据(例如所有执行程序共享的小字典或小表)。
  • 累加器在 Spark 执行程序之间提供可写副本,可用于实现分布式计数器(如在 MapReduce 中)或求和。

其他故障排除

相关信息

优化 AWS Glue 中的内存管理

在大型组中读取输入文件

在 Amazon EMR 上成功管理 Apache Spark 应用程序内存的最佳实践

使用 Apache Spark Web UI 监控任务

AWS 官方
AWS 官方已更新 2 年前