為何 AWS Glue ETL 任務會長時間執行?

上次更新日期︰2021 年 8 月 20 日

我的 AWS Glue 任務執行了很長時間。

-或-

我的 AWS Glue 落後者任務需要很長時間才能完成。

簡短描述

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:使用 AWS Glue UpdateJob API 搭配 enable-metrics 作為 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,然後導覽至執行程式標籤,以檢查特定的執行程式是否執行更長時間。如果是這樣,可用資源的任務分佈不均勻,以及可用資源利用不足可能是由於資料集中的資料偏差所致。在階段標籤中,您可以取得長時間執行階段的詳細資訊和統計資料。您可以找到這些階段是否涉及昂貴且耗時的隨機流出的詳細資訊。

資料處理單元 (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。