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

最終更新日: 2020 年 1 月 8 日

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

簡単な説明

「スレーブが失われました」というエラーは、クラスター内のノードが終了したか、利用できなかったために 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 は新しいコンテナをスケジュールしません。詳細については、Hadoop ドキュメントの NodeManager を参照してください。

異常なノードのために複数の Spark エグゼキュターが強制終了された場合、アプリケーションは「スレーブが失われました」というエラーで失敗します。

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 つが終了すると、「スレーブが失われました」というエラーが発生することがあります。スポットインスタンスは、以下の理由で終了する場合があります。

  • スポットインスタンス料金が上限価格を超えている。
  • スポットインスタンスの需要を満たすのに十分な未使用の EC2 インスタンスがない。

詳細については、「中断の理由」を参照してください。

この問題を解決するには:

Amazon EC2 Auto Scaling ポリシー

スケーリングポリシーで多数のスケールインおよびスケールアウトのイベントを順番に実行すると、新しいノードは前のノードで使用したものと同じ IP アドレスを取得することがあります。スケールインイベント中に Spark アプリケーションが実行されている場合、停止されたノードは Spark ブラックリストに追加され、エグゼキュターがそのノードで起動しないようにします。別のスケールアウトイベントが発生し、新しいノードが以前に停止したノードと同じ IP アドレスを取得した場合、YARN は新しいノードが有効であると見なし、エグゼキュターのスケジュールを試みます。ただし、ノードがまだ Spark ブラックリストに載っているため、そのノードでエグゼキュターを起動しようとすると失敗します。最大失敗数に達すると、Spark アプリケーションは「スレーブが失われました」というエラーで失敗します。

この問題を解決するには:

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

詳細については、Spark enhancements for elasticity and resiliency on Amazon EMR を参照してください。