在Hadoop生态系统中,YARN(Yet Another Resource Negotiator)作为核心的资源管理器,负责集群资源的分配与任务调度,无论是运行MapReduce、Spark还是其他计算框架的任务,都离不开YARN的支撑,在生产环境中,作业运行失败是难以完全避免的挑战,当作业失败时,如何快速、准确地定位问题根源,是保障数据处理链路稳定性的关键,本文将系统性地介绍如何查看和诊断YARN中报错的任务,从命令行到Web UI,从日志分析到常见错误场景,提供一套完整的排查思路和实践方法。
第一步:快速定位失败的作业
当怀疑有作业运行失败时,首要任务是识别出具体是哪个应用出了问题,YARN提供了强大的命令行工具来查询应用状态。
最常用的命令是 yarn application -list
,为了更高效地筛选,可以直接指定查看失败状态的作业:
yarn application -list -appStates FAILED
该命令会列出所有最终状态为 FAILED
的应用,输出结果通常包含以下关键字段:
列名 | 描述 |
---|---|
Application-Id | 应用的唯一标识符,后续所有操作都依赖它。 |
Application-Name | 应用提交时设置的名称。 |
Application-Type | 应用类型,如 MAPREDUCE, SPARK。 |
User | 提交应用的用户。 |
Queue | 应用所在的资源队列。 |
Final-State | 应用的最终状态(FAILED、KILLED、SUCCEEDED等)。 |
Finish-Time | 应用结束的时间戳。 |
找到了目标应用的 Application-Id
(application_1234567890123_0001
)后,可以使用以下命令获取该应用的详细状态信息:
yarn application -status application_1234567890123_0001
该命令会返回一个更详细的报告,包括启动时间、进度、跟踪URL以及最重要的 Diagnostics
(诊断信息)字段,有时,失败的直接原因会简要地显示在这个字段中,Application failed with state ‘FAILED’ due to ‘AM container for appattempt_… exited with exitCode: 1’”,这给出了初步的线索,但要深入分析,必须查看日志。
第二步:深入日志分析
日志是定位问题的“金矿”,YARN的日志体系主要分为三部分:ApplicationMaster(AM)日志、任务(Container)日志以及NodeManager/ResourceManager日志,对于用户而言,前两者最为关键。
命令行方式
获取应用完整日志最直接的方式是使用 yarn logs
命令,这个命令会聚合该应用所有相关的日志(包括AM和所有任务容器的日志)并输出到标准输出。
yarn logs -applicationId application_1234567890123_0001
面对海量的日志输出,直接阅读效率低下,强烈建议结合Linux的文本处理工具进行过滤和分析:
- 查找错误信息:使用
grep
忽略大小写(-i
)查找包含 “error”, “exception”, “fatal”, “failed” 等关键词的行。yarn logs -applicationId application_1234567890123_0001 | grep -i "error|exception|fatal"
- 查找特定任务的日志:日志通常会按容器(container)进行分割,你可以先找到报错容器的ID,再针对性地查看。
- 保存日志到文件:如果日志量很大,可以先将其重定向到文件,再使用文本编辑器慢慢分析。
yarn logs -applicationId application_1234567890123_0001 > app_failed_logs.txt
在分析日志时,要重点关注 Caused by
部分的Java堆栈跟踪,这通常会精确指出错误发生的类名和代码行数,是定位代码级Bug最直接的依据。
Web UI方式
对于不习惯命令行的用户,YARN的Web UI提供了更直观的日志查看体验。
- 访问ResourceManager UI:在浏览器中打开 ResourceManager 的Web地址,通常是
http://<rm-host>:8088
。 - 找到失败应用:在“ALL Applications”页面,可以通过状态过滤器筛选“FAILED”状态的应用。
- 进入应用详情页:点击失败应用的ID,进入其详情页面。
- 查看诊断与日志:
- Diagnostics信息:页面顶部会显示关键的诊断信息。
- AM UI链接:如果应用有UI(如Spark UI),这里会提供一个“Tracking UI”的链接,点击可以进入应用自身的监控界面,获取更详细的分析。
- 容器列表:向下滚动,可以看到该应用所有容器的列表,包括它们的状态、所在的NodeManager主机、以及日志链接。
- 查看容器日志:点击某个容器的“logs”链接,可以直接在浏览器中查看该容器的
stdout
、stderr
和syslog
,对于失败的任务,stderr
文件通常包含了错误堆栈信息。
Web UI的优势在于可以清晰地看到每个任务的生命周期和资源使用情况,并能方便地在不同容器的日志之间切换,非常适合进行可视化排查。
第三步:常见错误类型与排查思路
通过日志分析,我们可以将报错归纳为以下几种常见类型,并采取相应的排查策略。
错误现象/日志关键字 | 可能原因 | 排查与解决方案 |
---|---|---|
Container exited with a non-zero exit code 137 , Killed by YARN , MemoryLimitExceeded | 内存溢出(OOM):任务容器申请的内存不足以支撑其运行,被YARN强制杀死。 | 检查任务日志,确认是内存问题,2. 调整任务内存配置,如增加mapreduce.map.memory.mb 、mapreduce.reduce.memory.mb (MapReduce)或spark.executor.memory 、spark.driver.memory (Spark),3. 检查代码是否存在内存泄漏或不合理的数据加载。 |
Application submitted by user ... to queue ... was rejected as the queue ... is currently at full capacity | 队列资源不足:作业提交的队列已达到其资源容量上限,无法分配新的Container。 | 检查队列配置(capacity-scheduler.xml 或fair-scheduler.xml ),2. 等待队列资源释放,3. 将作业提交到其他可用队列,4. 调整队列的资源配额。 |
java.lang.NullPointerException , java.lang.ClassNotFoundException , java.io.FileNotFoundException | 应用代码异常:这是最常见的错误,源于程序本身的逻辑缺陷、配置错误或依赖问题。 | 仔细分析日志中的Java堆栈跟踪,定位到具体的代码行,2. 检查代码逻辑,修复空指针、类型转换等错误,3. 确认所有依赖的JAR包都已正确分发到集群,4. 检查HDFS上的输入文件路径是否存在且可读。 |
NodeManager ... is marked unhealthy because ... | 节点健康问题:作业运行的某个NodeManager节点因磁盘空间不足、CPU/内存负载过高等原因被标记为不健康,导致其上的任务失败。 | 登录到不健康的NodeManager节点,2. 检查磁盘空间(df -h )、系统负载(top )、内存使用情况,3. 清理磁盘,释放资源,4. 检查NodeManager的日志,获取更详细的健康检查失败原因。 |
小编总结与最佳实践
排查YARN报错作业是一个系统化的过程,遵循“定位应用 -> 获取状态 -> 分析日志 -> 归因解决”的路径,可以高效地解决大部分问题,在实际操作中,建议结合命令行的高效和Web UI的直观,形成自己的排查习惯,先用命令行快速定位和获取日志,再用Web UI进行可视化确认和深度分析,理解YARN的基本原理,如资源调度模型、容器生命周期等,将有助于在面对复杂问题时,能够从更高维度进行思考和判断。
相关问答FAQs
Q1: 当我执行 yarn logs -applicationId <appId>
时,命令报错或者提示“Logs are not available”,这是什么原因?我该如何获取日志?
A1: 这种情况通常是由YARN的日志聚合功能配置引起的,日志聚合功能(由参数 yarn.log-aggregation-enable
控制)负责在应用结束后,将散落在各个NodeManager节点上的日志收集并归档到HDFS上的一个指定目录(由 yarn.nodemanager.remote-app-log-dir
配置)。
- 日志聚合功能未启用。
yarn.log-aggregation-enable
设置为false
,yarn logs
命令将无法工作,因为日志在应用结束后仍保留在各个节点的本地,且可能会被定时清理。 - 日志已过期被清理。 即使启用了日志聚合,归档在HDFS上的日志也有保留期限(由
yarn.log-aggregation.retain-seconds
控制),超过这个时间的日志会被自动删除。
解决方案:
- 确认配置:联系集群管理员,确认
yarn.log-aggregation-enable
是否为true
。 - 手动获取日志(如果聚合未启用):如果功能未启用,你需要从Web UI上找到失败任务所在的NodeManager主机,然后SSH登录到该主机,在NodeManager的本地日志目录(通常配置为
yarn.nodemanager.log-dirs
)下,根据applicationId
和containerId
手动查找日志文件,这种方式非常繁琐且不可靠。 - 检查HDFS上的归档:如果功能已启用但提示不可用,可以尝试直接在HDFS上查看归档日志,路径通常是:
/logs/<user>/logs/<applicationId>
,你可以使用hdfs dfs -ls
和hdfs dfs -cat
命令来查看,如果这里也没有,说明日志可能已被清理,最好的长期解决方案是建议管理员启用日志聚合并设置合理的保留时间。
Q2: 如何区分是YARN平台本身的问题,还是我提交的应用程序自身的问题?
A2: 这是一个很关键的诊断点,区分这两者可以让你知道该找谁解决问题(开发团队还是运维团队),核心判断依据是和错误信息。
YARN平台问题的特征:
- 错误信息通用化:报错信息通常与资源、调度、集群环境相关,Queue resource limit exceeded”、“NodeManager is unhealthy”、“Failed to localize resources”、“ApplicationMaster launch failed, exitCode: 10”等。
- 日志来源:错误信息多出现在
ApplicationMaster
的日志中,描述的是YARN在尝试为你的应用分配资源、启动容器的过程中遇到的困难,而不是你的业务代码逻辑。 - 影响范围:通常会影响多个不相关的应用,或者某个队列/节点上的所有应用都出现问题。
应用程序自身问题的特征:
- 错误信息具体化:报错信息是程序语言(如Java)的异常堆栈,
java.lang.NullPointerException at com.mycompany.MyClass.process(MyClass.java:123)
,这是最明确的信号。 - 日志来源:错误信息几乎总是出现在具体任务(Task/Container)的
stderr
日志文件中。 - 影响范围:问题通常只局限于当前这个应用或某类特定输入数据,换一个输入数据,或者修改代码后,问题可能就消失了。
- 错误信息具体化:报错信息是程序语言(如Java)的异常堆栈,
快速判断方法:
- 首先查看
yarn application -status <appId>
的Diagnostics
信息,如果这里明确提到了资源、队列或节点问题,那多半是平台问题。 - 如果诊断信息模糊,直接使用
yarn logs ... | grep -i "exception"
或类似命令,如果搜索到了Java的Exception
堆栈,那99%是应用代码问题。 - 如果没有找到应用异常,但作业依然失败,再回头仔细分析AM日志和YARN系统日志,寻找平台层面的错误线索。
【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!
发表回复