YARN 如何处理单个 Container(如 Task 级别)运行失败的情况?
在 Hadoop YARN 架构中,处理单个 Container(通常对应一个 Task,如 MapReduce 的 Map 任务或 Spark 的 Executor/Task)运行失败的机制,是 YARN 核心组件(NodeManager、ResourceManager) 与 特定应用程序的 ApplicationMaster (AM) 协同合作的结果。
这里最核心的原则是:YARN 负责监控和报告资源的死活,而 ApplicationMaster 负责决定应用程序的业务逻辑(如是否重试、去哪里重试、何时宣告整个任务失败)。
以下是 YARN 处理单个 Container 运行失败的完整流程和细节:
1. 故障检测 (NodeManager 的职责)
当一个 Container 正在运行时,它所在的机器上的 NodeManager (NM) 会持续监控该 Container 的进程。
- 进程异常退出: 如果 Container 内的代码抛出未捕获的异常(如
NullPointerException),或者被操作系统强制杀死,进程会返回一个非零的退出码(Exit Code)。 - 内存超限 (OOM): 如果 Container 使用的物理内存 (Physical Memory) 或虚拟内存 (Virtual Memory) 超出了 YARN 分配给它的上限,NodeManager 会主动将其 Kill 掉(通常退出码为 137 或 143)。
- 检测结果: NM 察觉到 Container 失败后,会清理该 Container 在本地的临时工作目录,并准备将状态上报。
2. 状态上报 (NodeManager -> ResourceManager)
- NodeManager 会通过定期的心跳机制 (Heartbeat) 与 ResourceManager (RM) 保持通信。
- 在心跳信息中,NM 会告诉 RM:“分配给我这台机器上的 Container ID
xxx已经运行失败了,退出码是yyy,诊断信息是zzz”。 - RM 收到消息后,会在内部状态机中将该 Container 的状态更新为
FAILED,并释放该 Container 占用的集群资源(CPU 和 内存),以便将其分配给其他请求。
3. 通知 ApplicationMaster (ResourceManager -> ApplicationMaster)
- 负责管理该应用程序的 ApplicationMaster (AM) 也会定期向 RM 发送心跳(通常是通过
allocateRPC 调用,既用于申请新资源,也用于获取现有资源的状态)。 - 当 AM 发送下一次心跳时,RM 会在心跳响应中包含一个列表,告知 AM:“你管辖下的 Container
xxx已经失败了”。
4. 容错与重试决策 (ApplicationMaster 的职责)
这是最关键的一步。AM 收到 Container 失败的通知后,会根据所在计算框架(如 MapReduce、Spark、Flink)的容错策略进行处理:
- 标记 Task 失败: AM 会将运行在该 Container 中的 Task 标记为失败。
- 申请新 Container (重试): 绝大多数框架都会进行重试。AM 会再次向 RM 发起资源申请,要求一个新的 Container 来重新运行这个失败的 Task。
- 节点黑名单机制 (Node Blacklisting): 为了防止由于某台机器硬件故障导致 Task 反复失败,AM 通常会采用黑名单机制。如果某个 Task 在同一台 NodeManager 上连续失败多次,AM 在向 RM 申请新 Container 时,会明确要求避开那台有问题的机器,将任务调度到其他健康的节点上。
- 达到最大重试次数: 框架通常会有一个最大重试次数的限制。
- 例如,在 MapReduce 中,默认一个 Map Task 允许失败 4 次(通过
mapreduce.map.maxattempts配置)。 - 如果该 Task 重试了 4 次依然失败,AM 就会判定这个 Task 彻底失败。
- 一旦核心 Task 彻底失败,AM 通常会宣告整个 Application (Job) 失败,并主动通知 RM 注销自己。
- 例如,在 MapReduce 中,默认一个 Map Task 允许失败 4 次(通过
5. 日志与清理
- 日志聚合: 如果开启了 YARN 的日志聚合功能(Log Aggregation),当整个 Application 结束(或失败)后,NodeManager 会将该失败 Container 的运行日志上传到 HDFS。开发者可以通过
yarn logs -applicationId <app_id>命令查看该 Container 失败的具体堆栈信息。 - 状态展示: 在 YARN ResourceManager 的 Web UI 上,开发者可以点进对应的 Application,查看到处于
FAILED状态的 Container 及其诊断信息(Diagnostics),比如Container killed by YARN for exceeding memory limits。
总结
YARN 对单个 Container 失败的处理遵循 “发现 -> 汇报 -> 决策 -> 重试/终止” 的闭环:
- NM 负责发现进程死亡或内存超限。
- RM 负责回收资源并汇报给 AM。
- AM 负责业务上的决策,通常会向 RM 申请新资源在其他节点上重试任务。
- 如果重试超过框架配置的阈值,AM 会将整个作业标记为失败。