Amazon EMR の Spark で「Container killed by YARN for exceeding memory limits (メモリ制限を超えたために YARN によってコンテナが強制終了されました)」というエラーを解決するにはどうすればよいですか?
Amazon EMR 上の Spark での「Container killed by YARN for exceeding memory limits (メモリ制限を超えたために YARN によってコンテナが強制終了されました)」というエラーをトラブルシューティングしたいと考えています。
簡単な説明
このエラーを解決するには、次のいずれかの方法を使用します。
- メモリオーバーヘッドを増やす。
- エグゼキュターコアの数を減らす。
- パーティション数を増やす。
- ドライバーとエグゼキューターのメモリを増やす。
解決方法
このエラーの根本的な原因と適切な解決策は、ワークロードによって異なります。エラーをトラブルシューティングするには、次の順序で、以下の各方法を試す必要があります。この順番で次の方法に進む前に、前のセクションの 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" } } ]
単一のジョブでは:
spark-submit を実行するときにメモリオーバーヘッドを増やすには、--conf オプションを使用します。
例:
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" } } ]
単一のジョブでは:
spark-submit を実行するときにエグゼキューターコアの数を減らすには、--executor-cores オプションを使用します。
例:
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 Datasets の spark.default.parallelism の値を増やすか、または .repartition() 操作を実行します。パーティション数を増やすと、パーティションごとに必要なメモリ量が減ります。Spark は、速度を最大化する効果的な方法として、クラスター RAM を多用しています。したがって、Ganglia でメモリ使用量をモニタリングし、クラスター設定とパーティション化戦略がデータ拡大のニーズを満たしていることを確認する必要があります。それでも「Container killed by YARN for exceeding memory limits (メモリ制限を超えたために YARN によってコンテナが強制終了されました)」というエラーメッセージが表示される場合は、ドライバーとエグゼキューターのメモリを増やします。
ドライバーとエグゼキューターのメモリを増やす
エラーがドライバーコンテナまたはエグゼキューターコンテナのいずれかで発生した場合は、ドライバーとエグゼキューターの両方ではなく、ドライバーまたはエグゼキューターのどちらかでメモリを増やしてください。ドライバーまたはエグゼキューターメモリとドライバーまたはエグゼキューターメモリのオーバーヘッドの合計が常に、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 インスタンスに、ワークロードに必要なメモリリソースがない可能性があります。より大きなメモリ最適化インスタンスタイプに切り替えると、エラーが解決する場合があります。インスタンスタイプを変更してもメモリ例外が発生する場合は、新しいインスタンスでこれらのトラブルシューティング方法を試してください。
関連情報
Amazon EMR の Spark で「java.lang.ClassNotFoundException」を解決するにはどうすればよいですか?
関連するコンテンツ
- 質問済み 1年前lg...
- 質問済み 2年前lg...
- 質問済み 1年前lg...
- 質問済み 7年前lg...
- AWS公式更新しました 2年前