Amazon EMR の Spark で ExecutorLostFailure「Slave lost (スレーブが失われました) 」というエラーを解決するには、どうすれば良いですか?

最終更新日: 2020 年 9 月 24 日

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.shYARN_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 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 の機能強化」 を参照してください。