Apache Spark アプリケーションを Amazon EMR クラスターに送信しました。アプリケーションが次のエラーで失敗します。
「Most recent failure: Lost task 1209.0 in stage 4.0 (TID 31219, ip-xxx-xxx-xx-xxx.compute.internal, executor 115): ExecutorLostFailure (executor 115 exited caused by one of the running tasks) Reason: Slave lost (最新の失敗: ステージ 4.0 (TID 31219, ip-xxx-xxx-xx-xxx.compute.internal, executor 115) でタスク 1209.0 が失われました。ExecutorLostFailure (エクゼキューター 115 は実行中のタスクにより終了しました。)理由:スレーブが失われました。」
簡単な説明
このエラーは、ノードが終了したか、利用できなくなったために Spark タスクが失敗したことを示しています。このエラーには、多数の原因が考えられます。次の解決方法では、これらの一般的な根本原因について説明します。
- 高いディスク使用率
- クラスターノードでのスポットインスタンスの使用
- 過剰な Amazon Elastic Compute Cloud (Amazon EC2) Auto Scaling ポリシー
解決方法
高いディスク使用率
Hadoop では、NodeManager はクラスターのノードにアタッチされている Amazon Elastic Block Store (Amazon EBS) ボリュームを定期的にチェックします。1 つのボリュームがアタッチされたノードのディスク使用率が、YARN プロパティ yarn.nodemanager.disk-health-checker.max-disk-utilization-per-disk-percentage (デフォルト値は 90%) よりも大きい場合、ノードは異常であると見なされます。ノードが異常である場合、ResourceManager はそのノードで実行されているすべてのコンテナを強制終了します。異常なノードでは、ResourceManager は新しいコンテナをスケジュールしません。詳細については、Hadoop ドキュメントの 「NodeManager」 を参照してください。
異常なノードのために ResourceManager が複数のエグゼキュータを強制終了させた場合は、アプリケーションは「Slave lost (スレーブが失われました) 」というエラーで失敗します。NodeManager ログまたはインスタンスコントローラーログを調べると、ノードが異常であることを確認できます。
- NodeManager ログの場所は、yarn-env.sh の YARN_LOG_DIR 変数で定義されます。
- インスタンスコントローラーログは、マスターノードの /emr/instance-controller/log/instance-controller.log に保存されます。インスタンスコントローラーログは、クラスターのすべてのノードの集約ビューを提供します。
ノードが異常である場合、ログには次のようなエントリが表示されます。
2019-10-04 11:09:37,163 INFO Poller: InstanceJointStatusMap contains 40 entries (R:40):
i-006baxxxxxx 1829s R 1817s ig-3B ip-xxx-xx-xx-xxx I: 7s Y:U 11s c: 0 am: 0 H:R 0.0%Yarn unhealthy Reason : 1/1 local-dirs are bad: /mnt/yarn; 1/1 log-dirs are bad: /var/log/hadoop-yarn/containers
i-00979xxxxxx 1828s R 1817s ig-3B ip-xxx-xx-xx-xxx I: 7s Y:R 9s c: 3 am: 2048 H:R 0.0%
i-016c4xxxxxx 1834s R 1817s ig-3B ip-xxx-xx-xx-xxx I: 13s Y:R 14s c: 3 am: 2048 H:R 0.0%
i-01be3xxxxxx 1832s R 1817s ig-3B ip-xxx-xx-xx-xxx I: 10s Y:U 12s c: 0 am: 0 H:R 0.0%Yarn unhealthy Reason : 1/1 local-dirs are bad: /mnt/yarn; 1/1 log-dirs are bad: /var/log/hadoop-yarn/containers
この問題を解決するには、コアノードとタスクノードにアタッチされている EBS ボリュームのサイズを増やします。または、HDFS から未使用のデータを削除します。
スポットインスタンス
EMR クラスターノードに Amazon EC2 スポットインスタンス を使用している場合で、そのうちの 1 つが終了すると、「Slave lost (スレーブが失われました) 」というエラーが発生することがあります。スポットインスタンスは、以下の理由で終了する場合があります。
- スポットインスタンス料金が上限価格を超えてます。
- スポットインスタンスの需要を満たすのに十分な未使用の EC2 インスタンスがない。
詳細については、「中断の理由」を参照してください。
この問題を解決するには :
- オンデマンドインスタンスへの切り替えを検討してください。
- Amazon EMR リリースバージョン 5.11.0 以前を使用している場合は、最新バージョンへのアップグレードを検討してください。
Amazon EC2 Auto Scaling ポリシー
スケーリングポリシーで多数のスケールインおよびスケールアウトのイベントを順番に実行すると、新しいノードは前のノードで使用したものと同じ IP アドレスを取得することがあります。スケールインイベント中に Spark アプリケーションが実行されている場合、Spark は停止されたノードを拒否リストに追加し、エグゼキュターがそのノードで起動しないようにします。別のスケールアウトイベントが発生し、新しいノードが以前に停止したノードと同じ IP アドレスを取得した場合、YARN は新しいノードが有効であると見なし、エグゼキュターのスケジュールを試みます。ただし、ノードがまだ Spark 拒否リストに載っているため、そのノードでエグゼキュターを起動しようとすると失敗します。最大失敗数に達すると、Spark アプリケーションは「Slave lost (スレーブが失われました) 」というエラーで失敗します。
この問題を解決するには :
Spark 拒否リストからノードを削除するには、次の例に示すように Spark および YARN のタイムアウトプロパティを減らします。
/etc/spark/conf/spark-defaults.conf に次のプロパティを追加します。これで停止状態のノードが拒否リストに残る時間を短縮できます。デフォルトは 1 時間です。詳細については、「ノード停止の動作設定」を参照してください。
spark.blacklist.decommissioning.timeout 600s
/etc/hadoop/conf/yarn-site.xml で次の YARN プロパティを変更します。このプロパティは、実行中のコンテナとアプリケーションの完了を待ってから、停止ノードを停止状態に移行するまでの時間を指定します。デフォルトは 3600 秒です。
yarn.resourcemanager.nodemanager-graceful-decommission-timeout-secs 600
詳細については、「Amazon EMR の伸縮性と回復力を高めるための Spark の機能強化」 を参照してください。
関連情報
クラスターの設定のガイドラインとベストプラクティス
Amazon EMR の Spark ジョブにおけるステージ障害の問題を解決するには、どうすれば良いですか?