如何解决 AWS Glue ETL 任务中的“设备上没有剩余空间”错误?

2 分钟阅读
0

我想避免在运行 AWS Glue ETL 任务时出现“设备上没有剩余空间”错误。

简短描述

运行 AWS Glue 提取、转换、加载(ETL)作业时,可能会出现以下类型的错误:

  • 由于阶段故障,任务中止: 阶段 158.0 的任务 68 失败了 4 次,最近一次失败: 阶段 158.0 的任务 68.3 丢失(TID 28820,10.102.100.111,执行程序 17):org.apache.spark.memory.SparkOutOfMemoryError:在 org.apache.spark.shuffle.sort.ShuffleExternalSorter@55f6dabb 上调用 spill() 时出错: 设备上没有剩余空间

        -或者-

  • 由于阶段故障,任务中止: ResultStage 7 的失败次数已达到上限: 4.最近一次失败原因:org.apache.spark.shuffle.MetadataFetchFailedException: 缺少 shuffle 2 的输出位置

Apache Spark 使用 AWS Glue 工作线程上的本地磁盘从内存中溢出了超出 spark.executor.memory 配置参数所定义的堆空间的数据。

诸如 groupByKey()reduceByKey()join() 等宽转换可能会导致数据重组。在作业的排序或重组阶段,Spark 会先将中间数据写入本地磁盘,然后才能在不同的工作线程之间交换这些数据。此时可能会出现“设备上没有剩余空间”或 MetadataFetchFailedException 错误。当执行程序上剩余的磁盘空间不足且无法恢复时,Spark 会引发此错误。

解决方法

这些类型的错误通常发生在处理作业观察到数据集出现明显偏差的情况下。本节介绍了一些常见的监控和调试异常以及解决这些异常的方法。

AWS Glue 任务指标Apache Spark UI 是监控 Apache Spark 执行程序是否存在数据偏差的强大工具。该工具可监控实施时间表,帮助您轻松识别任何可能导致数据偏差的问题。它可以帮助您详细了解每个阶段、任务、作业和执行程序的行为。

分解计算和存储

这种方法可以扩展存储以应对大型数据重组事件,而不是将数据写入 AWS Glue 工作线程的本地磁盘。

**使用专用的无服务器存储:**使用 AWS Glue 2.0 或更高版本,可借助 Amazon Simple Storage Service(Amazon S3)存储 Spark 重组和溢出数据。

AWS Glue 2.0 利用以下作业参数,在 AWS Glue 中使用 Amazon S3 重组数据。有关详细信息,请参阅 Amazon S3 的 AWS Glue Spark 重组插件

  • 键:--write-shuffle-files-to-s3
    **值:**TRUE
  • 键:--write-shuffle-spills-to-s3
    **值:**TRUE
  • 键:--conf
    **值:**spark.shuffle.glue.s3ShuffleBucket=s3://custom_shuffle_bucket
    **注意:**可选标志 spark.shuffle.glue.s3ShuffleBucket 指定了您写入重组文件的 Amazon S3 桶。请将 custom_shuffle_bucket 替换为您的 S3 桶的名称。

AWS Glue 3.0/4.0 利用以下任务参数使用适用于 Apache Spark 的 Cloud Shuffle 存储插件。有关详细信息,请参阅适用于 Apache Spark 的 Cloud Shuffle 存储插件

  • 键:--write-shuffle-files-to-s3
    **值:**TRUE
  • 键:--conf
    **值:**spark.shuffle.storage.path=s3://custom_shuffle_bucket
    **注意:**可选标志 spark.shuffle.storage.path 指定了您写入重组文件的 Amazon S3 桶。请将 custom_shuffle_bucket 替换为您的 S3 桶的名称。

横向扩展

横向扩展是指通过横向扩展增加工作线程数量或通过纵向扩展来升级工作线程类型。但是,横向扩展可能并不总是奏效,尤其是在您的数据严重偏向几个键的情况下。要解决数据偏差问题,可以考虑通过实施加盐技术来修改 Apache Spark 应用程序逻辑。

减少和筛选输入数据

尽可能对输入数据进行预先筛选,最大限度地减少广泛操作期间的数据重组和网络占用。利用以下技术有效筛选数据:

广播小表

连接 Apache Spark 中的表,会在不同工作线程的执行程序之间触发数据重组和海量数据移动。这可能会导致系统耗尽内存并将数据溢出到工作线程的磁盘上。为了最大限度地减少网络开销,Spark 支持使用较小表进行广播。这些表最多只有数十 MB(兆字节),可防止数据分区和重组。向 Spark 提供提示后,即可使用小表进行广播。有关详细信息,请参阅 AWS 博客在 AWS Glue 中优化内存管理中的广播小表

使用 AQE

来自 Databricks 的自适应查询执行(AQE)是 Spark SQL 中的一种优化技术。该技术使用运行时系统统计数据来选择最有效的查询实施计划,以解决每个阶段的数据偏差和动态重组分区问题。AWS Glue 3.0/4.0 默认支持 AQE。

AQE 执行以下功能:

  • 动态合并重组分区
    在每个查询阶段结束后,根据需要自动合并分区并解决分区管理问题。有关详细信息,请参阅动态合并重组分区,它位于 Databricks 网站上的自适应查询执行: 在运行时系统上加速 Spark SQL
    **– 分区太少:**自动拆分包含多余数据的分区,因为这些分区会导致溢出到本地磁盘。
    **– 分区太多:**根据需要自动合并分区。当每个分区的数据规模很小且仅需提取少量网络数据即可读取重组块时,分区就会合并。

  • 动态切换连接策略
    根据每个阶段的表大小统计数据,将 Sort-Merge 转换为广播哈希连接

  • 动态优化偏差连接
    从重组文件统计数据中自动检测和优化偏差连接。AQE 将偏差分区拆分为较小的子分区。然后,AQE 会将这些较小分区连接到另一个节点中的相应分区。有关详细信息,请参阅动态优化偏差连接,它位于 Databricks 网站上的自适应查询执行: 在运行时系统上加速 Spark SQL

配置 AQE

使用以下任务参数启用 AQE:

  • 键:--conf
    值: spark.sql.adaptive.enabled=true --conf spark.sql.adaptive.coalescePartitions.enabled=true --conf spark.sql.adaptive.skewJoin.enabled=true
AWS 官方
AWS 官方已更新 1 年前