スキップしてコンテンツを表示

AWS Glue の ETL ジョブが失敗し、"Container killed by YARN for exceeding memory limits" エラーが発生する原因を教えてください。

所要時間1分
0

AWS Glue の抽出、変換、ロード (ETL) ジョブが失敗し、"Container killed by YARN for exceeding memory limits" エラーが発生します。

簡単な説明

このエラーの一般的な原因は以下のとおりです。

  • 基盤となる Apache Spark クラスターのメモリーしきい値を超えるメモリーを大量に消費する操作。これらの操作には、大規模テーブルの結合や、分布に偏りがあるデータセットの処理などが当てはまります。
  • それぞれのエグゼキューターに割り当てられている量よりも多くのメモリを消費するデータのファットパーティション。
  • 分割できない大容量ファイルが原因で、メモリ内のパーティションが増大した場合。

解決策

このエラーを解決するには、次の 1 つまたは複数の手順を実行します。

ワークタイプをアップグレードする

G.2x 構成では利用可能なメモリが増えるため、ワーカータイプをアップグレードします。ワーカータイプを G.1x から次のワーカータイプにアップグレードできます。

  • G.2x
  • G.4x
  • G.8x
  • G.12
  • 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 to other databases (他のデータベースに対する JDBC)」を参照してください。

ETL ジョブで高パフォーマンス関数を使用する

ETL ジョブでは、特に Python または Scala コードを Spark の関数やメソッドと組み合わせる場合は、ユーザー定義関数の使用を避けてください。たとえば、if/else ステートメントや for ループにおいて、空の DataFrames を検証する際は、Spark の df.count() を用いないようにします。代わりに、df.schema()df.rdd.isEmpty() などの、パフォーマンスに優れた関数を使用してください。

AWS Glue ジョブのテストと最適化

AWS Glue ジョブを本番環境で実行する前に、インタラクティブセッションで AWS Glue をテストし、ETL コードを最適化します。

上記の解決方法がいずれも機能しない場合は、入力データをチャンクまたはパーティションに分割します。次に、単一の大規模ジョブを実行するのではなく、複数の AWS Glue ETL ジョブを実行するようにします。詳細については、「実行に上限を設定してワークロードをパーティション化する」を参照してください。

関連情報

OOM 例外とジョブの異常のデバッグ

Best practices to scale Apache Spark jobs and partition data with AWS Glue (AWS Glue を使用して Spark ジョブをスケーリングし、データを分割する際のベストプラクティス)

Optimize memory management in AWS Glue (AWS Glue でのメモリ管理を最適化する)

AWS公式更新しました 6ヶ月前
コメントはありません

関連するコンテンツ