我的 AWS Glue 擷取、轉換和載入 (ETL) 作業失敗,並顯示「Container killed by YARN for exceeding memory limits」的錯誤訊息。
簡短描述
以下是導致此錯誤的常見原因:
- 超出基礎 Apache Spark 叢集記憶體閾值的高記憶體密集作業。這些作業可能包括聯結大型資料表或處理在分佈上偏斜的資料集。
- 使用過多記憶體的資料分區,其所消耗的記憶體超過指派給對應執行程式的記憶體。
- 無法拆分的大型檔案導致形成大型記憶體內分區。
解決方法
若要解決此錯誤,請完成以下一個或多個解決方案。
升級工作類型
由於 G.2x 具有較高的記憶體組態,請升級工作者類型。您可以將工作者類型從 G.1x 升級為下列其中一種:
- G.2x
- G.4x
- G.8x
- G.12x
- G.16x
- R.1x
- R.2x
- R.4x
- R.8x
如需工作者類型規格的更多資訊,請參閱為 Spark 作業定義作業屬性和 AWS Glue 版本。
增加作業的執行程式數量
如果升級工作者類型後錯誤仍然存在,請增加作業的執行程式數量。每個執行程式都有一定數量的核心。此數量決定執行程式可處理的分區數量。工作者類型會定義資料處理單元 (DPU) 的 Spark 組態。
更新資料
為了確保 AWS Glue 在重組作業 (例如聯結) 之前能夠平均使用執行程式,請驗證您的資料是否平行化。若要在所有執行程式間重新分割資料,請在您的 ETL 作業中加入以下其中一個命令。
對於 DynamicFrame,請加入以下命令:
dynamicFrame.repartition(totalNumberOfExecutorCores)
對於 DataFrame,請加入以下命令:
dataframe.repartition(totalNumberOfExecutorCores)
使用作業書籤
當您使用作業書籤時,書籤會讓 AWS Glue 作業只處理新寫入的檔案。此組態可減少 AWS Glue 作業處理的檔案數量,並降低記憶體問題。書籤會儲存前一次執行中已處理檔案的中繼資料。在之後的執行中,作業會比較時間戳記,然後決定是否再次處理這些檔案。如需更多資訊,請參閱使用作業書籤追蹤已處理的資料。
使用 DynamicFrame 平行讀取資料
當您連線到 JDBC 資料表時,Spark 預設只開啟一個並行連線。驅動程式會嘗試在單一 Spark 執行程式中一次性下載整個資料表。此下載可能需要較長時間,並可能導致執行程式發生記憶體不足 (OOM) 錯誤。請改為設定 JDBC 資料表的特定屬性,以指示 AWS Glue 使用 DynamicFrame 平行讀取資料。或者,您也可以使用 Spark DataFrame 來達成從 JDBC 平行讀取的效果。如需更多資訊,請參閱 Spark 網站上的 JDBC 到其他資料庫。
在 ETL 作業中使用高效能函數
在 ETL 作業中請勿使用使用者定義的函數 (UDF),特別是當您將 Python 或 Scala 程式碼與 Spark 的函數和方法結合使用時。例如,請勿在 if/else 陳述式或 for 迴圈中使用 Spark 的 df.count() 來驗證空的 DataFrame。請改為使用效能更佳的函數,例如 df.schema() 或 df.rdd.isEmpty()。
測試並最佳化 AWS Glue 作業
在生產環境中執行 AWS Glue 作業之前,請在互動式工作階段中測試 AWS Glue 作業並最佳化 ETL 程式碼。
如果上述解決方案都無法奏效,請將輸入資料分割成多個區塊或分區。然後,執行多個 AWS Glue ETL 作業,而不是執行單一大型作業。如需詳細資訊,請參閱限定執行的工作負載分割。
相關資訊
對 OOM 例外和作業異常偵錯
使用 AWS Glue 擴展 Spark 作業和分區資料的最佳實務
最佳化 AWS Glue 中的記憶體管理