如何解決 AWS Glue Spark 任務中的「java.lang.OutOfMemoryError: Java 堆積空間」錯誤?

2 分的閱讀內容
0

我的 AWS Glue 任務失敗,並顯示「Command failed with exit code 1」(命令失敗,隨附結束代碼 1)。Amazon CloudWatch Logs 顯示錯誤「java.lang.OutOfMemoryError: Java 堆積空間」。

簡短描述

「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 操作,從工作節點收集結果,然後將它們作為單一物件傳回至驅動程式。結果可能非常大,並使驅動程式不堪重負。預設情況下,Spark 組態 spark.driver.maxResultSize 設定為 1 GB,有助於保護驅動程式免於過度負荷。

因此,請限制這些動作,並在可能的情況下改用 take()takeSample()isEmpty() 等動作。

另請注意,如果關聯 (表格) 大小超過驅動程式的可用記憶體,Spark 內的廣播聯結可能導致 OOM 錯誤。在將關聯廣播至執行程式之前,它會在驅動程式節點上具體化。如果正在廣播多個表格,或者關聯過大,那麼驅動程式可能會遇到記憶體不足的問題。使用 Spark 組態 spark.sql.autoBroadcastJoinThresholdSpark Join Hints 進行控制。

定期銷毀共享變數

請務必謹慎使用共享變數。當您不再需要共享變數時,請進行銷毀,因為這些變數可能造成 Spark 驅動程式 OOM 例外狀況。共享變數有兩種類型,分別是廣播變數和累加器。

  • 廣播變數是只會傳送給執行程式一次的唯讀資料。它們是儲存不可變參考資料的良好解決方案,例如在所有執行程式間共享的小字典或小型資料表。
  • 累加器在 Spark 執行程式之間提供可寫入複本,並可用於執行分散式計數器 (例如 MapReduce) 或加總。

其他疑難排解

相關資訊

最佳化 AWS Glue 中的記憶體管理

讀取大型群組中的輸入檔案

在 Amazon EMR 上成功管理 Apache Spark 應用程式記憶體的最佳做法

使用 Apache Spark Web UI 監控任務

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