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

Amazon EMR の Spark で発生する「Container killed by YARN for exceeding memory limits」というエラーを解決する方法を教えてください。

所要時間2分
0

Amazon EMR の Spark で発生する「Container killed by YARN for exceeding memory limits」というエラーを解決したいです。

簡単な説明

次のいずれかの手順で、このエラーを解決します。

  • メモリオーバーヘッドを増やします。
  • エグゼキューターコアの数を減らします。
  • パーティションの数を増やします。
  • ドライバーおよびエグゼキュータのメモリを増やします。

解決策

このエラーの根本原因と適切な解決策は、ワークロードによって異なります。このエラーを解決するには、以下の各方法を次の順序で試す必要がある場合があります。このシーケンスの次の方法に進む前に、前のセクションで spark-defaults.conf に加えた変更をすべて元に戻してください。

メモリオーバーヘッドを増やす

メモリオーバーヘッドは、各エグゼキューターに割り当てられたオフヒープメモリの量です。デフォルトでは、メモリーオーバーヘッドはエグゼキューターメモリーの 10% または 384 のうち、高い方に設定されます。メモリオーバーヘッドは、Java NIO ダイレクトバッファ、スレッドスタック、共有ネイティブライブラリ、またはメモリマップファイルに使用されます。

メモリのオーバーヘッドを段階的に、最大 25% まで増やすことを検討してください。ドライバーまたはエグゼキューターのメモリとメモリオーバーヘッドの合計は、使用しているインスタンスタイプの yarn.nodemanager.resource.memory-mb より小さい必要があります。

spark.driver/executor.memory + spark.driver/executor.memoryOverhead < yarn.nodemanager.resource.memory-mb

ドライバーコンテナまたはエグゼキューターコンテナでエラーが発生した場合は、そのコンテナのみでメモリオーバーヘッドを増やすことを検討してください。クラスターの実行中、新しいクラスターの起動時、またはジョブの送信時にメモリオーバーヘッドを増やすことができます。

実行中のクラスター:

マスターノードの spark-defaults.conf を変更します。

例:

sudo vim /etc/spark/conf/spark-defaults.conf

spark.driver.memoryOverhead 512
spark.executor.memoryOverhead 512

新しいクラスター:

クラスターの起動時に、次のような設定オブジェクトを追加します。

[
  {
    "Classification": "spark-defaults",
    "Properties": {
      "spark.driver.memoryOverhead": "512",
      "spark.executor.memoryOverhead": "512"
    }
  }
]

単一のジョブ用:

--conf オプションを使用すると、spark-submit の実行時にメモリのオーバーヘッドを増やすことができます。

例:

spark-submit --class org.apache.spark.examples.SparkPi --master yarn --deploy-mode cluster --conf spark.driver.memoryOverhead=512 --conf spark.executor.memoryOverhead=512 /usr/lib/spark/examples/jars/spark-examples.jar 100

メモリーのオーバーヘッドを増やしても問題が解決しない場合は、エグゼキューターコアの数を減らしてください。

エグゼキューターコアの数を減らす

エグゼキューターが実行できるタスクの最大数が減るため、必要なメモリ量が削減されます。このエラーが発生したドライバーコンテナやその他のエグゼキューターコンテナに応じて、ドライバーまたはエグゼキューターのコアを減らすことを検討してください。

実行中のクラスター:

マスターノードの spark-defaults.conf を変更します。

例:

sudo vim /etc/spark/conf/spark-defaults.conf
spark.driver.cores  3
spark.executor.cores  3

新しいクラスター:

クラスターの起動時に、次のような設定オブジェクトを追加します。

[
  {
    "Classification": "spark-defaults",
    "Properties": {"spark.driver.cores" : "3",
      "spark.executor.cores": "3"
    }
  }
]

単一のジョブ用:

--executor-cores オプションを使用すると、spark-submit の実行時にエグゼキューターコアの数を減らすことができます。

例:

spark-submit --class org.apache.spark.examples.SparkPi --master yarn --deploy-mode cluster --executor-cores 3 --driver-cores 3 /usr/lib/spark/examples/jars/spark-examples.jar 100

エラーメッセージが解消されない場合は、パーティションの数を増やしてください。

パーティションの数を増やす

パーティションの数を増やすには、未加工の Resilient Distributed データセットで spark.default.parallelism の値を増やすか、.repartition() 操作を実行します。パーティションの数を増やすと、パーティションごとに必要なメモリ量が削減されます。Spark は、効果的に速度を最大化するためにクラスタ RAM を多用しています。したがって Ganglia でメモリ使用量を監視し、クラスター設定とパーティショニング戦略がデータ需要の増加に対応できることを確認する必要があります。「Container killed by YARN for exceeding memory limits」というエラーメッセージが解消されない場合は、ドライバーとエグゼキューターのメモリを増やしてください。

ドライバーまたはエグゼキューターのメモリを増やす

このエラーがドライバーコンテナまたはエグゼキューターコンテナで発生する場合は、ドライバーまたはエグゼキューターのメモリを増やすことを検討してください (両方では増やさないでください)。ドライバーまたはエグゼキューターの合計メモリと、ドライバーまたはエグゼキューターのメモリオーバーヘッドを合計した値が、常に使用している EC2 インスタンスタイプの yarn.nodemanager.resource.memory-mb 値よりも小さいことを確認してください。

spark.driver/executor.memory + spark.driver/executor.memoryOverhead < yarn.nodemanager.resource.memory-mb

実行中のクラスター:

マスターノードの spark-defaults.conf を変更します。

例:

sudo vim /etc/spark/conf/spark-defaults.conf

spark.executor.memory  1g
spark.driver.memory  1g

新しいクラスター:

クラスターの起動時に、次のような設定オブジェクトを追加します。

[
  {
    "Classification": "spark-defaults",
    "Properties": {
      "spark.executor.memory": "1g",
      "spark.driver.memory":"1g",
    }
  }
]

単一のジョブ用:

spark-submit を実行する際、--executor-memory および --driver-memory オプションを使用してメモリを増やします。

例:

spark-submit --class org.apache.spark.examples.SparkPi --master yarn --deploy-mode cluster --executor-memory 1g --driver-memory 1g /usr/lib/spark/examples/jars/spark-examples.jar 100

その他の解決策

エラーメッセージが解消されない場合は、次のことを試してください。

  • ベンチマーク サンプルデータセットに対してアプリケーションを実行することをおすすめします。この方法では、メモリの問題につながる可能性のある速度低下や不均等なパーティションを特定しやすくなります。
  • データのフィルター: 処理するデータ量は最小限であることを確認してください。データをフィルターしなかったり、アプリケーションの実行の後半でフィルター処理を行ったりした場合、過剰なデータが原因でアプリケーションの速度が低下する可能性があります。結果的に、メモリ例外が発生する可能性が高くなります。
  • データセットのサイズ: 必要最小限のデータを処理することをおすすめします。データを分割し、必要なデータのみが取り込まれるようにします。
  • パーティショニング戦略: 別のパーティショニング戦略の使用を検討してください。たとえば、代替キーでパーティション分割を行うと、大容量のパーティションや不均等なパーティションを避けることができます。
  • EC2 インスタンスタイプ: EC2 インスタンスには、ワークロードに必要なメモリリソースがない可能性があります。大容量のメモリ最適化インスタンスタイプに切り替えると、エラーが解決する場合があります。インスタンスタイプを変更してもメモリ例外が発生する場合は、新しいインスタンスでトラブルシューティング方法を試してください。

関連情報

Spark の構成

Amazon EMR の Spark で「java.lang.ClassNotFoundException」が発生する場合の解決方法を教えてください

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

関連するコンテンツ