AWS Glue Spark ジョブの「java.lang.OutOfMemoryError: Java heap space」(java.lang.OutOfMemoryError: Java ヒープの容量) エラーを解決する方法を教えてください。

所要時間2分
0

AWS Glue ジョブが「Command failed with exit code 1」(終了コード 1 でコマンドが失敗しました) というメッセージで失敗します。Amazon CloudWatch Logs に、「java.lang.OutOfMemoryError: Java heap space」(java.lang.OutOfMemoryError: Java ヒープの容量) エラーが表示されます。

簡単な説明

「java.lang.OutOfMemoryError: Java heap space」(java.lang.OutOfMemoryError: Java ヒープの容量) エラーは、ドライバーまたはエグゼキューターが JVM メモリを使い果たしていることを示します。OOM の原因がドライバーなのかエグゼキューターなのかを判断するには、「OOM 例外とジョブ異常のデバッグ」を参照してください。

: 以下の解決方法は、ドライバーの OOM 例外のみに適用されます。

ドライバーの OOM 例外は次の原因で発生します。

  • AWS Glue Spark ジョブで、Amazon Simple Storage Service (Amazon S3) から多数の小さなファイルを読み取る
  • collect()、ブロードキャスト結合、共有変数などのドライバー負荷の高い操作を行う

解決方法

多数の小さなファイルが原因で発生するドライバーの OOM 例外を解決する

DynamicFrames を含む多数の小さなファイルが原因で発生するドライバーの OOM 例外を解決するには、次の 1 つまたは複数の方法を使用します。

useS3ListImplementation をアクティブ化する

ファイルを一覧表示すると、AWS Glue はドライバーのメモリリストにファイルインデックスを作成します。useS3ListImplementationTrue に設定すると、AWS Glue はファイルのリストをメモリに一度にキャッシュしません。代わりに、AWS Glue はリストをバッチでキャッシュします。そのため、ドライバーがメモリ不足になる可能性が低くなります。

from_cataloguseS3ListImplementation をアクティブ化する方法については、次の例を参照してください。

datasource0 = glueContext.create_dynamic_frame.from_catalog(database = "database", table_name = "table", additional_options = {'useS3ListImplementation': True}, transformation_ctx = "datasource0")

from_cataloguseS3ListImplementation をアクティブ化する次の例を参照してください。

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 の結合のヒントを使用してください。

共有変数を定期的に破棄する

共有変数は慎重に使用してください。共有変数は、Spark ドライバーの OOM 例外を引き起こす可能性があるため、不要になったら破棄してください。共有変数には、ブロードキャスト変数とアキュムレータの 2 種類があります。

  • ブロードキャスト変数は読み取り専用データで、エグゼキューターに 1 回だけ送信されます。すべてのエグゼキューター間で共有される小さな辞書や小さなテーブルなどの、不変の参照データを保存するのに適したソリューションです。
  • アキュムレータは Spark エグゼキューター間で書き込み可能なコピーを提供するもので、(MapReduce のように) 分散カウンタや合計を実装するのにも使えます。

その他のトラブルシューティング

関連情報

AWS Glue でのメモリ管理を最適化する

大きなグループでの入力ファイルの読み取り

Amazon EMR で Apache Spark アプリケーションのメモリを正常に管理するためのベストプラクティス

Apache Spark ウェブ UI を使用したジョブの監視

AWS公式
AWS公式更新しました 2年前
コメントはありません