为什么我的 AWS Glue ETL 任务运行很长时间?

上次更新时间:2021-08-20

我的 AWS Glue 任务运行了很长时间。

-或者-

我的 AWS Glue straggler 任务完成需要很长时间。

简短描述

AWS Glue 任务完成需要很长时间的某些常见原因如下:

  • 大型数据集
  • 数据集中的数据分配不均
  • 执行程序之间的任务分配不均
  • 资源调配不足

解决方案

启用指标

AWS Glue 提供了 Amazon CloudWatch 指标,可用于提供有关执行程序及各执行程序完成的工作量的信息。通过执行以下任一操作,您可以在 AWS Glue 任务上启用 CloudWatch 指标:

使用特殊参数:将以下参数添加到您的 AWS Glue 任务中。此参数允许您收集任务分析指标以用于任务运行。这些指标可在 AWS Glue 控制台和 CloudWatch 控制台上获取。

Key: --enable-metrics

使用 AWS Glue 控制台:要在现有任务上启用指标,请执行以下操作:

  1. 打开 AWS Glue 控制台
  2. 在导航窗格中,选择 Jobs(任务)
  3. 选择要为其启用指标的任务。
  4. 选择 Action(操作),然后选择 Edit job(编辑任务)
  5. Monitoring options(监控选项)下,选择 Job metrics(任务指标)
  6. 选择 Save(保存)

使用 API:使用带 --enable-metrics的 AWS Glue UpdateJob API 作为 DefaultArguments 参数,以启用现有任务的指标。

注意:AWS Glue 2.0 不使用报告指标的 YARN。这意味着您无法获得 AWS Glue 2.0 的某些执行程序指标,例如 numberMaxNeededExecutors 和 numberAllExecutor。

启用连续日志记录

如果您在 AWS Glue 任务中启用连续日志记录,实时驱动程序和执行程序日志每五秒钟会向 CloudWatch 推送一次。借助这些实时日志记录信息,您可以获得有关运行任务的更多详细信息。有关更多信息,请参阅启用 AWS Glue 任务的连续日志记录

检查驱动程序和执行程序日志

在驱动程序日志中,对运行了很长时间才完成的任务进行检查。例如:

2021-04-15 10:53:54,484 ERROR executionlogs:128 - g-7dd5eec38ff57a273fcaa35f289a99ecc1be6901:2021-04-15 10:53:54,484 INFO [task-result-getter-1] scheduler.TaskSetManager (Logging.scala:logInfo(54)): Finished task 0.0 in stage 7.0 (TID 139) in 4538 ms on 10.117.101.76 (executor 10) (13/14)
...
2021-04-15 12:11:30,692 ERROR executionlogs:128 - g-7dd5eec38ff57a273fcaa35f289a99ecc1be6901:2021-04-15 12:11:30,692 INFO [task-result-getter-3] scheduler.TaskSetManager (Logging.scala:logInfo(54)): Finished task 13.0 in stage 7.0 (TID 152) in 4660742 ms on 10.117.97.97 (executor 11) (14/14)

在这些日志中,您可以查看需要 77 分钟才能完成的单个任务。使用此信息,您可以查看需要很长时间完成该特定任务的原因。您可以通过使用 Apache Spark web UI 来实现。Spark UI 为不同阶段、任务和执行程序提供结构良好的信息。

启用 Spark UI

您可以使用 Spark UI 对长时间运行的 Spark 任务进行故障排除。通过启动 Spark 历史记录服务器并启用 Spark UI 日志,您可以获得有关阶段和任务的信息。您可以使用日志了解工件如何执行任务。您可以使用 AWS Glue 控制台或 AWS Command Line Interface (AWS CLI) 启用 Spark UI。有关更多信息,请参阅启用用于 AWS Glue 任务的 Apache Spark Web UI

任务完成后,您可能会看到类似于以下内容的驱动程序日志:

ERROR executionlogs:128 - example-task-id:example-timeframe INFO [pool-2-thread-1] s3n.MultipartUploadOutputStream (MultipartUploadOutputStream.java:close(414)): close closed:false s3://dox-example-bucket/spark-application-1626828545941.inprogress

分析任务日志后,您可以在 Amazon Elastic Compute Cloud (Amazon EC2) 实例上或使用 Docker 启动 Spark 历史记录服务器。打开 UI,然后导航到 Executor(执行程序)选项卡以检查特定执行程序是否运行了更长时间。若是如此,则任务分配不均和可用资源利用不足可能是数据集中的数据偏斜造成的。在 Stages(阶段)选项卡中,关于需要很长时间的阶段,您可以获得更多信息和统计数据。您可以找到有关这些阶段是否涉及昂贵且耗时的随机溢出的详细信息。

数据处理单元 (DPU) 的容量规划

如果所有执行程序的任务执行量相同,但任务仍然需要很长时间才能完成,那么您可以考虑在任务中增加更多工件以提高速度。DPU 容量规划可以帮助您避免以下情况:

  • 调配不足可能会导致执行时间减慢
  • 过度调配会导致更高的成本,但会在相同的时间内提供结果

从 CloudWatch 指标中,您可以获取有关当前使用的执行程序数以及所需的最大执行程序数的信息。所需的 DPU 数量取决于输入分区的数量以及请求的工件类型。

定义输入分区的数量时,请记住以下几点:

  • 如果 Amazon Simple Storage Service (Amazon S3) 文件不可拆分,则分区数等于输入文件的数量。
  • 如果 Amazon S3 文件可拆分,且数据是非结构化/半结构化的,则分区数等于文件总大小/64 MB。如果各文件大小均小于 64 MB,则分区数等于文件数量。
  • 如果 Amazon S3 文件可拆分且数据结构化,则分区数等于文件总大小/128 MB。

执行以下操作来计算 DPU 的最佳数量:

例如,假设输入分区的数量为 428 个。然后,您可以通过以下公式计算 DPU 的最佳数量:

所需的最大执行程序数 = 输入分区数/每个执行程序的任务数 = 428/4 = 107

请记住以下内容:

  • 标准工件类型支持每个执行程序运行 4 个任务
  • G.1X 支持每个执行程序运行 8 个任务
  • G.2X 支持每个执行程序运行 16 个任务

标准工件类型在一个节点中有两个执行程序(包括一个驱动程序)。其中一个执行程序是 Spark 的驱动程序。因此,您需要 108 个执行程序。

所需的 DPU 数量 =(执行程序数量/各节点的执行程序数量)+ 1 个 DPU = (108/2) +1 = 55。


这篇文章对您有帮助吗?


您是否需要账单或技术支持?