我向 Amazon EMR 集群提交了 Apache Spark 应用程序。应用程序失败,并出现以下错误:
"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 任务因节点终止或不可用而失败。造成此错误的原因有很多。以下解决方法涵盖了这些常见的根本原因:
- 高磁盘利用率
- 集群节点使用 Spot 实例
- Amazon Elastic Compute Cloud (Amazon EC2) Auto Scaling 策略过于激进
解决方法
高磁盘利用率
在 Hadoop 中,NodeManager 会定期检查附加到集群节点的 Amazon Elastic Block Store (Amazon EBS) 卷。如果连接了一个卷的节点上的磁盘利用率大于 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 删除不使用的数据。
Spot 实例
如果您为 EMR 集群节点使用 Amazon EC2 Spot 实例,而其中一个实例终止,则可能会出现“从属丢失”错误。Spot 实例可能由于以下原因而终止:
- Spot Instant 价格大于您的最大出价。
- 没有足够的未使用 EC2 实例来满足对 Spot 实例的需求。
有关更多信息,请参阅中断原因。
要解决此问题:
- 请考虑切换到按需实例。
- 如果您使用的是 Amazon EMR 发行版 5.11.0 或更早版本,请考虑升级到最新版本。
Amazon EC2 Auto Scaling 策略
当扩展策略按顺序执行许多内缩和外扩事件时,新节点可能会获得与先前节点使用的 IP 地址相同的 IP 地址。如果在内缩事件期间运行 Spark 应用程序,则 Spark 会将停用节点会添加到拒绝清单,以防止执行程序在该节点上启动。如果发生另一个外扩事件,并且新节点获得与先前停用节点相同的 IP 地址,则 YARN 会认为新节点有效,并尝试在其上安排执行程序。但是,由于该节点仍在 Spark 拒绝清单中,因此在在该节点上尝试启动执行程序的操作失败。当达到最大失败次数时,Spark 应用程序将失败,并显示“slave lost”(从属丢失)错误。
要解决此问题:
要从 Spark 拒绝清单中删除节点,需减小 Spark 和 YARN 超时属性,如以下示例所示:
在 /etc/spark/conf/spark-defaults.conf 中添加以下属性。这样可缩短处于停用状态的节点被列于拒绝清单的时间。默认值为一小时。有关更多信息,请参阅配置节点停用行为。
spark.blacklist.decommissioning.timeout 600s
在 /etc/hadoop/conf/yarn-site.xml 中修改以下 YARN 属性。此属性指定在将停用节点转变为停用状态之前等待正在运行的容器和应用程序完成的时间。默认值为 3600 秒。
yarn.resourcemanager.nodemanager-graceful-decommission-timeout-secs 600
有关更多信息,请参阅 Spark 对 Amazon EMR 的弹性和韧性的增强。
相关信息
集群配置指南和最佳实践
如何排查 Amazon EMR 上 Spark 作业中的阶段故障?