YARN 命令行是 Web UI 的重要补充,也是日常排查里更稳定的入口。Web 页面适合看整体状态,命令行更适合做三件事:第一,快速确认应用、队列、节点和日志的真实状态;第二,把一次排查过程沉淀成可以复用的脚本;第三,在页面打不开、代理跳转失败、日志聚合页面异常时,仍然能从 ResourceManager、NodeManager 和 HDFS 里把关键证据取出来。
建议按 YARN 对象模型理解命令,而不是按命令名称硬背。一次作业提交后,首先产生的是 Application;ApplicationAttempt 是 Application 的一次运行实例;Attempt 对应 AM Container;普通任务、executor 或 shell 进程运行在普通 Container 里。Container 不只是“资源 + 进程”,还包含 LocalResource、Environment、Tokens、ACL 和启动命令等上下文。Application 要进入某个 Queue,Container 要落在某个 NodeManager 上,应用结束后日志进入聚合目录。只要这个对象链路清楚,常用命令就不会散。
下面的命令都在同一套 YARN 测试环境中验证过。为了让输出更接近真实排查场景,我先提交了一个 Distributed-Shell 示例应用,让两个 Container 执行一条简单命令;随后又提交了一个长时间运行的应用,用来验证 kill 操作。
yarn jar /opt/hadoop/share/hadoop/yarn/hadoop-yarn-applications-distributedshell-3.4.1.jar \
org.apache.hadoop.yarn.applications.distributedshell.Client \
-appname YarnCommandSuccessDemo \
-shell_command "echo YARN_COMMAND_SUCCESS_20250322; hostname; date; sleep 8" \
-num_containers 2 \
-master_memory 512 \
-container_memory 512
提交成功后,客户端输出里最值得看的是状态变化。这里能看到应用先被 ResourceManager 接收,随后 AM 启动,最后应用完成:
2025-03-22 10:24:03,387 INFO impl.YarnClientImpl: Submitted application application_1737508641558_0002
2025-03-22 10:24:04,414 INFO distributedshell.Client: ... appQueue=root.default, yarnAppState=ACCEPTED ...
2025-03-22 10:24:05,417 INFO distributedshell.Client: ... appQueue=root.default, yarnAppState=RUNNING ...
2025-03-22 10:24:17,451 INFO distributedshell.Client: ... yarnAppState=FINISHED, distributedFinalState=SUCCEEDED ...
这四行已经把 YARN 应用的核心生命周期串起来了:客户端拿到 Application ID,ResourceManager 接受提交,ApplicationMaster 注册并进入运行状态,最后 AM 向 RM 汇报完成状态。
1. 命令描述
先看 yarn –help 能看到的命令范围。可以从三个维度理解 YARN 命令:
| 类型 | 命令 | 作用 |
|---|---|---|
| application-level | application、app、applicationattempt、container、logs、jar | 提交应用、查看应用状态、查看 Attempt 和 Container、拉取日志 |
| cluster-level | node、queue、cluster、nodeattributes、classpath、envvars、version、top | 查看节点、队列、标签、属性、运行环境和集群使用情况 |
| admin-level | rmadmin、daemonlog、schedulerconf、routeradmin、scmadmin | 刷新配置、调整日志级别、管理调度器配置和相关服务 |
普通开发和排查最常用的是第一类和第二类。第三类偏管理员操作,执行前要确认影响范围。例如 rmadmin -refreshQueues 可以刷新队列配置,daemonlog -setlevel 可以临时修改服务日志级别,这些命令本身很有用,但不适合在不了解集群策略时随手执行。
如果把 yarn –help 的输出展开看,命令覆盖面其实比日常使用感知到的更广:
Admin Commands:
daemonlog get/set the log level for each daemon
node prints node report(s)
rmadmin admin tools
routeradmin router admin tools
scmadmin SharedCacheManager admin tools
Client Commands:
application prints application(s) report/kill application/manage long running application
applicationattempt
classpath
cluster
container
envvars
fs2cs
jar <jar>
logs
nodeattributes
queue
schedulerconf
timelinereader
top
version
Daemon Commands:
resourcemanager
nodemanager
proxyserver
router
sharedcachemanager
timelineserver
这里有一些命令看上去离普通作业排查很远,但在特定场景下会很有价值。fs2cs 用来把 Fair Scheduler 配置迁移到 Capacity Scheduler 配置,适合调度器迁移时评估配置差异;routeradmin 面向 YARN Federation 的 Router;scmadmin 面向 SharedCacheManager;timelinereader 和 Timeline Service 有关;resourcemanager、nodemanager 这类 daemon 命令则是服务启动入口。它们不一定每天都会用,但知道它们属于哪类对象,遇到迁移、联邦、共享缓存或服务启动问题时就不会无从下手。
我把这些命令再按“读操作”和“写操作”分一层。读操作包括 application -list、application -status、logs、node -list、node -status、queue -status、cluster -list-node-labels、nodeattributes -list、classpath、envvars、version。这些命令可以放心作为排查入口。写操作包括 application -kill、application -changeQueue、rmadmin -refresh*、daemonlog -setlevel、schedulerconf -add/-remove/-update、nodeattributes -add/-remove/-replace。写操作不是不能用,而是要带着对象、影响范围和回滚方式一起用。
2. 应用生命周期命令
应用侧命令围绕一条主线展开:先提交应用,再查看 Application 状态,必要时定位 ApplicationAttempt 和 Container,最后通过聚合日志还原运行过程。日常排查里,这一组命令的使用频率最高。
2.1 application:查看和控制应用
yarn application 是使用频率最高的命令。它能查看应用列表、查询应用详情、杀掉应用,也能对部分长运行服务做管理。日常最常用的是 -list、-status 和 -kill。
查看所有状态的应用:
yarn application -list -appStates ALL
输出如下:
Total number of applications (application-types: [], states: [NEW, NEW_SAVING, SUBMITTED, ACCEPTED, RUNNING, FINISHED, FAILED, KILLED] and tags: []):2
Application-Id Application-Name Application-Type User Queue State Final-State Progress Tracking-URL
application_1737508641558_0002 YarnCommandSuccessDemo YARN root root.default FINISHED SUCCEEDED 100% N/A
application_1737508641558_0001 QuasiMonteCarlo MAPREDUCE root root.default FINISHED SUCCEEDED 100% http://lavm-bzoq5mwl1h:19888/jobhistory/job/job_1737508641558_0001
这张列表适合先做粗判断。State 是 ResourceManager 记录的应用生命周期状态,Final-State 是 ApplicationMaster 汇报的最终结果。一个应用可能处于 FINISHED,但 Final-State 是 FAILED 或 KILLED,所以排查时不能只看 State。Progress=100% 也不等于业务正确,它只说明框架上报的进度已经到达终点。Application-Type 也很重要,它能区分 MapReduce、YARN 原生应用、Spark、Tez 等不同框架。
Tracking-URL 通常指向 RM proxy UI 或框架自己的历史页面。运行中的应用经常通过 RM proxy 跳到 AM Web UI;已经结束的 MapReduce 作业可能指向 JobHistoryServer。这个字段能帮助定位页面入口,但最终证据仍要回到 Diagnostics 和日志。
如果只想看正在运行的应用,可以缩小状态范围:
yarn application -list -appStates RUNNING
如果集群里应用很多,还可以按类型过滤:
yarn application -list -appTypes MAPREDUCE
查询单个应用详情:
yarn application -status application_1737508641558_0002
关键输出如下:
Application Report :
Application-Id : application_1737508641558_0002
Application-Name : YarnCommandSuccessDemo
Application-Type : YARN
User : root
Queue : root.default
State : FINISHED
Final-State : SUCCEEDED
AM Host : lavm-bzoq5mwl1h/172.16.0.6
Aggregate Resource Allocation : 33065 MB-seconds, 31 vcore-seconds
Log Aggregation Status : SUCCEEDED
Diagnostics :
这份报告里有几个字段非常实用。Queue 可以确认应用是否进了预期队列;AM Host 可以定位 ApplicationMaster 跑在哪台机器;Aggregate Resource Allocation 能粗略反映应用消耗;Log Aggregation Status 决定后面能不能直接用 yarn logs 拉日志;Diagnostics 是失败应用的第一现场,很多资源不足、AM 启动失败、权限错误都会先出现在这里。
杀掉应用使用 -kill:
yarn application -kill application_1737508641558_0003
真实输出如下:
Killing application application_1737508641558_0003
2025-03-22 10:24:45,878 INFO impl.YarnClientImpl: Killed application application_1737508641558_0003
再查状态,可以看到最终结果已经变成 KILLED:
Application Report :
Application-Id : application_1737508641558_0003
Application-Name : YarnCommandKillDemo
State : KILLED
Final-State : KILLED
Log Aggregation Status : SUCCEEDED
Diagnostics : Application application_1737508641558_0003 was killed by user root at 127.0.0.1
-kill 是很直接的操作,适合处理明显误提交、资源占用异常、已经确认没有业务价值的任务。生产环境里通常还要结合队列、用户和应用名确认,不要只凭 Application ID 操作。
application 还有一些不那么常用但需要知道的选项,例如 -changeQueue 可以移动应用队列,-appStates 可以按状态过滤,-appTags 可以按标签过滤。队列迁移是否成功取决于调度器和队列配置,不是所有状态下的应用都适合迁移。
应用状态过滤值得单独记一下。YARN 里的常见状态包括:
| 状态 | 含义 | 排查重点 |
|---|---|---|
| NEW、NEW_SAVING | 应用刚创建或正在保存初始状态 | 一般停留很短,长时间停留要看 RM 状态存储 |
| SUBMITTED | 客户端已经提交给 RM | 检查队列、权限、AM 资源请求 |
| ACCEPTED | RM 接受应用,等待 AM Container | 重点看队列容量、节点资源、标签约束 |
| RUNNING | AM 已启动,应用正在运行 | 重点看 AM 日志和普通 Container 日志 |
| FINISHED | 应用生命周期结束 | 必须继续看 Final-State |
| FAILED | 应用失败 | 先读 Diagnostics,再拉 AM 日志 |
| KILLED | 应用被杀掉 | 确认是谁杀掉、为何杀掉、是否有外部调度系统介入 |
State 和 Final-State 的区别是排查里非常常见的误区。State=FINISHED 只表示 RM 侧生命周期结束,不表示成功;真正表示 AM 汇报结果的是 Final-State。所以脚本里判断作业是否成功时,不要只 grep FINISHED,应该同时判断 Final-State=SUCCEEDED。即便两者都成功,也只能说明 YARN 生命周期成功,业务输出是否正确还要看框架日志和结果路径。
2.2 logs:拉取聚合日志
应用失败后,第一步看 application -status,第二步通常就是 yarn logs。只要日志聚合成功,下面这条命令就能把应用相关 Container 日志拉出来。YARN 日志通常要分三层看:Client 日志说明提交侧发生了什么,AM 日志说明应用协调器做了什么决策,普通 Container 日志说明具体执行单元为什么失败。
yarn logs -applicationId application_1737508641558_0002
为了验证日志确实来自普通 Container,我在示例命令里输出了一个固定标记:
yarn logs -applicationId application_1737508641558_0002 | grep YARN_COMMAND_SUCCESS_20250322
输出片段如下:
Container: container_1737508641558_0002_01_000002 on lavm-bzoq5mwl1h_41925
exec /bin/bash -c "echo YARN_COMMAND_SUCCESS_20250322; hostname; date; sleep 8 ..."
YARN_COMMAND_SUCCESS_20250322
Container: container_1737508641558_0002_01_000003 on lavm-bzoq5mwl1h_41925
exec /bin/bash -c "echo YARN_COMMAND_SUCCESS_20250322; hostname; date; sleep 8 ..."
YARN_COMMAND_SUCCESS_20250322
这里可以看到两个普通 Container 都执行了同一条 shell 命令。对 Distributed-Shell 来说,这就是业务输出;对 MapReduce 来说,类似位置会出现 Mapper、Reducer、AM 的 stdout、stderr 和 syslog。
常用的日志参数有这些:
yarn logs -applicationId <app_id>
yarn logs -applicationId <app_id> -am 1
yarn logs -applicationId <app_id> -log_files stdout
yarn logs -applicationId <app_id> -log_files stderr
yarn logs -applicationId <app_id> -size 4096
yarn logs -applicationId <app_id> -out /tmp/yarn-logs
yarn logs -applicationId <app_id> -show_container_log_info
-am 1 适合只看第一个 AM Container;-log_files 用来限制日志文件名;-size 可以避免一次输出过大;-out 适合把日志下载到本地目录再慢慢分析;-show_container_log_info 能先列出有哪些 Container 日志,避免盲目拉全量。
如果 yarn logs 查不到日志,先检查应用详情里的 Log Aggregation Status。如果状态不是 SUCCEEDED,问题可能在日志聚合配置、NodeManager 本地日志保留、HDFS 权限或应用结束时间上。不要一上来就判断“任务没有日志”。
日志命令还有两个实用细节。第一,-size 支持限制输出大小,适合先看尾部错误:
yarn logs -applicationId <app_id> -log_files stderr -size 8192
第二,-out 会按应用和 Container 组织本地文件,适合做离线分析:
yarn logs -applicationId <app_id> -out /tmp/yarn-log-download
当应用日志很多时,不建议直接把全量日志打到终端。更好的方式是先用 -show_container_log_info 看 Container 和日志文件,再有针对性地拉 stderr、stdout 或 syslog。MapReduce 作业可以优先看 AM 的 syslog 和失败 task 的 stderr;Distributed-Shell 这种简单应用则直接看普通 Container 的 stdout。
2.3 applicationattempt:定位 AM Attempt
Application 是用户看到的应用,ApplicationAttempt 是应用的一次运行尝试。AM 启动失败后重试,就会出现多个 Attempt;每一次 retry 都会产生新的 attemptId。很多“应用一直失败重试”的问题,不看 Attempt 很难说清楚。
查看某个应用的 Attempt:
yarn applicationattempt -list application_1737508641558_0002
输出如下:
Total number of application attempts :1
ApplicationAttempt-Id State AM-Container-Id Tracking-URL
appattempt_1737508641558_0002_000001 FINISHED container_1737508641558_0002_01_000001 http://lavm-bzoq5mwl1h:8088/proxy/application_1737508641558_0002/
继续查看 Attempt 详情:
yarn applicationattempt -status appattempt_1737508641558_0002_000001
关键字段如下:
Application Attempt Report :
ApplicationAttempt-Id : appattempt_1737508641558_0002_000001
State : FINISHED
AMContainer : container_1737508641558_0002_01_000001
Tracking-URL : http://lavm-bzoq5mwl1h:8088/proxy/application_1737508641558_0002/
AM Host : lavm-bzoq5mwl1h/172.16.0.6
这个命令的价值在于把 Application 和 AM Container 接起来。AM Container 是 RM 分配、NM 启动的 Container,它和当前 attempt 的生命周期绑定。应用失败时,可以先用 applicationattempt -list 找到失败的 AM Container,再用 yarn logs -applicationId 或 Container 日志入口看 AM 的 stderr 和 syslog。AM 报错通常比客户端报错更接近根因,例如 classpath 缺失、LocalResource 下载失败、ContainerLaunchContext 命令错误、权限不足等。
2.4 container:查看运行单元
Container 是 YARN 资源分配和进程启动的基本单元。它是资源、启动上下文和运行环境的组合,不等于框架里的 executor、task 或进程本身。yarn container 可以列出 Attempt 下的 Container,也可以查看单个 Container 状态:
yarn container -list appattempt_1737508641558_0002_000001
yarn container -status <container_id>
不过这个命令有一个容易踩坑的地方:应用结束后,ResourceManager 不一定还保留完整 Container 报告。在这次验证里,应用已经完成后再查询 Container 列表,结果是空:
Total number of containers :0
Container-Id Start Time Finish Time State Host Node Http Address LOG-URL
这不是说应用没有 Container,而是说明 RM 只保留有限的历史 Container 报告,这时更适合从聚合日志追踪 Container。前面的 yarn logs 已经能看到 container_1737508641558_0002_01_000002 和 container_1737508641558_0002_01_000003 的输出。
因此我一般这样使用 Container 命令:应用还在运行时,用 container -list 和 container -status 看实时状态;应用已经结束后,以 applicationattempt 找 AM,以 logs 看 AM 和普通 Container 的日志。这样比强行依赖 Container 状态更稳定。
container 还支持 -signal 和 -shell 等操作,这些更偏运维调试。生产环境是否可用,要看集群安全策略、容器运行时和管理员权限。
Container ID 本身也有信息量。以 container_1737508641558_0002_01_000003 为例,中间的 0002 对应 Application 序号,01 对应 Attempt,最后的 000003 是当前 attempt 下的 Container 序号。通常 000001 是 AM Container,后续才是普通业务 Container。这个规律不是用来替代命令查询的,但能帮助快速判断一段日志来自 AM 还是来自普通任务。
3. 资源与调度命令
应用状态只能说明“任务自己发生了什么”,资源与调度命令负责回答另一个问题:集群有没有足够资源、队列是否允许运行、节点是否健康、标签和属性是否限制了调度。
3.1 node:查看 NodeManager 状态
YARN 应用最终要落在 NodeManager 上运行,所以节点命令是排查资源和健康状态的基础。
查看节点列表:
yarn node -list
输出如下:
Total Nodes:1
Node-Id Node-State Node-Http-Address Number-of-Running-Containers
lavm-bzoq5mwl1h:41925 RUNNING lavm-bzoq5mwl1h:8042 0
常用过滤方式:
yarn node -list -all
yarn node -list -states RUNNING
yarn node -list -states LOST,UNHEALTHY,DECOMMISSIONED
常见节点状态还包括 NEW、RUNNING、UNHEALTHY、DECOMMISSIONING、DECOMMISSIONED、LOST 和 REBOOTED。其中 UNHEALTHY 最常见的原因是本地磁盘、日志目录、权限或健康检查脚本失败;LOST 通常表示 RM 长时间收不到 NodeManager 心跳;DECOMMISSIONED 表示节点已经被下线,不应该继续接收新 Container。
节点详情使用 -status:
yarn node -status lavm-bzoq5mwl1h:41925
关键字段可以简化成这样看:
Node Report :
Node-Id : lavm-bzoq5mwl1h:41925
Rack : /default-rack
Node-State : RUNNING
Node-Http-Address : lavm-bzoq5mwl1h:8042
Containers : 0
Memory-Used : 0MB
Memory-Capacity : 12288MB
CPU-Used : 0 vcores
CPU-Capacity : 4 vcores
如果应用长时间处于 ACCEPTED,而队列容量看起来没问题,就应该检查节点是否足够、是否健康、是否有标签限制、是否还有可分配内存和 vcore。很多“调度器不分配资源”的问题,最后其实是 NodeManager 没注册、节点不健康、标签不匹配或资源上限配置过小。
node -status 里的资源字段要和应用请求一起看。比如 AM 请求 2048 MB,但队列只剩 1024 MB 可分配,或者 NodeManager 最大 Container 内存被限制在 1024 MB,应用就可能一直等。再比如应用指定了某个节点标签,而集群里没有带这个标签的可用节点,RM 也不会随便把它调度到其它节点上。NodeManager capacity 也不等于机器真实可用容量,它受 yarn.nodemanager.resource.*、系统预留、cgroups 和健康状态影响。命令行排查资源问题时,至少要把应用的队列、节点容量、节点状态和标签约束放在一起判断。
3.2 queue:查看队列状态
队列决定应用能使用哪部分资源。Capacity Scheduler 下,队列有容量、最大容量、状态、ACL、抢占等属性。命令行查看队列:
yarn queue -status root.default
输出片段如下:
Queue Information :
Scheduler Name : CapacityScheduler
Queue Name : default
Queue Path : root.default
State : RUNNING
Capacity : 100.00%
Current Capacity : .00%
Maximum Capacity : 100.00%
Maximum Parallel Apps : 2147483647
Accessible Node Labels : *
Preemption : disabled
这份输出适合确认几个问题:应用提交的队列是否存在;队列是否是 RUNNING;队列容量和最大容量是否符合预期;是否存在节点标签限制;是否启用了抢占。Maximum Capacity 还会受父队列上限影响,不是叶子队列写 100% 就一定能占满整个集群。Preemption: disabled 也很关键,它意味着调度器不会主动回收其它队列超额占用的资源,资源恢复到保障容量可能更慢。队列不对时,应用可能进入默认队列;队列不存在时,客户端可能提交失败;队列容量不足时,应用可能长时间等待。
如果配置了多级队列,还可以列出父队列下的子队列:
yarn queue -list root
队列命令只能看状态,不能替代配置检查。真正排查容量问题时,还要结合 capacity-scheduler.xml、Scheduler 页面和 rmadmin -refreshQueues 的执行结果一起看。
3.3 cluster、nodeattributes:标签和属性
节点标签和节点属性是资源隔离的重要工具。即便小集群不用,也应该知道怎么查。
查看节点标签:
yarn cluster -list-node-labels
当前环境没有配置标签,输出为空:
Node Labels:
查看节点属性:
yarn nodeattributes -list
输出如下:
Attribute Type
空输出不是错误,只表示当前没有定义属性。大集群里,节点属性可以用来表达硬件差异,例如磁盘类型、机型、机房、GPU 资源等。排查“应用为什么没有调度到某些节点”时,标签和属性都要检查。
nodeattributes 还支持 -add、-remove、-replace、-nodestoattributes、-attributestonodes 等操作。修改类操作属于集群管理范畴,不应该在业务排查里随便执行。
标签和属性的区别可以简单理解为:node labels 是 scheduling constraint,节点属性更偏 metadata。标签常用于把一批节点划给某类队列或应用;属性则可以表达更细的节点信息。应用真的出现“只在某些机器上失败”时,节点属性和节点标签会帮助缩小范围,但它们不能代替 NodeManager 日志和 Container 日志。
4. 管理与诊断命令
管理类命令会影响 ResourceManager、调度器或服务日志级别。它们不应该作为排查第一步,但在确认问题边界以后,可以用来刷新配置、验证 HA 状态、临时提高日志级别,或者检查动态调度器配置。
4.1 rmadmin:刷新和管理 ResourceManager
yarn rmadmin 是 ResourceManager 管理命令。最常见的用法是刷新配置:
yarn rmadmin -refreshQueues
这条命令执行成功时通常很安静,只会看到连接 ResourceManager 的日志,没有异常就说明刷新请求已经发出:
2025-03-22 10:24:38,215 INFO client.DefaultNoHARMFailoverProxyProvider: Connecting to ResourceManager at localhost/127.0.0.1:8033
常见刷新命令还有:
yarn rmadmin -refreshNodes
yarn rmadmin -refreshNodesResources
yarn rmadmin -refreshUserToGroupsMappings
yarn rmadmin -refreshSuperUserGroupsConfiguration
yarn rmadmin -refreshAdminAcls
yarn rmadmin -refreshServiceAcl
这些命令的含义不一样。-refreshQueues 面向调度器队列,只刷新 scheduler 相关配置,不刷新 RM 已有应用状态;-refreshNodes 面向节点纳管;-refreshNodesResources 面向节点资源配置;用户组和 ACL 刷新则与权限有关。执行前要确认改的是哪类配置文件,否则容易出现“刷新了但没生效”的误判。
在启用 ResourceManager HA 的集群里,rmadmin 还可以查看或切换服务状态;没有启用 HA 时执行相关命令会明确报错:
yarn rmadmin -getServiceState rm1
输出:
Cannot run -getServiceState when ResourceManager HA is not enabled
这个输出本身也有价值:它说明当前集群不是 RM HA 模式。排查 HA 相关问题时,先用命令确认模式,比直接猜配置更可靠。
启用 HA 后,-getServiceState 可以确认哪个 RM 是 active、哪个是 standby。手工切换 active/standby 属于高风险操作,通常只应该在维护窗口或故障切换流程中执行,并且要确认客户端和 Router 是否能跟随新的 active RM。
rmadmin 还有一个常被忽略的点:刷新命令不是“重新加载所有配置”。不同配置对应不同刷新入口。例如只改了队列容量,执行 -refreshNodes 没有意义;只改了节点资源,执行 -refreshQueues 也不会生效。看到“刷新后没变化”时,先确认刷新对象是否正确,再确认配置文件是否被 RM 读取到,最后再看 Web UI 或 queue -status 输出。
4.2 daemonlog:临时查看和调整日志级别
服务端日志级别有时需要临时调整。yarn daemonlog 可以通过 HTTP 接口查看或设置某个类的日志级别。
查看 ResourceManager 某个类的日志级别:
yarn daemonlog -getlevel localhost:8088 org.apache.hadoop.yarn.server.resourcemanager.ResourceManager
输出如下:
Connecting to http://localhost:8088/logLevel?log=org.apache.hadoop.yarn.server.resourcemanager.ResourceManager
Submitted Class Name: org.apache.hadoop.yarn.server.resourcemanager.ResourceManager
Log Class: org.slf4j.impl.Reload4jLoggerAdapter
Effective Level: INFO
临时调整日志级别的形式是:
yarn daemonlog -setlevel localhost:8088 org.apache.hadoop.yarn.server.resourcemanager.ResourceManager DEBUG
这类命令适合短时间定位问题,例如调度器为什么拒绝请求、AM 注册为什么异常、NodeManager 心跳里带了什么状态。定位完成后要及时恢复日志级别,避免 DEBUG 日志把磁盘打满。RM 是调度核心,过大的 DEBUG 日志还可能明显影响性能和响应时间。
日志级别调整的对象是具体类名,不是某个笼统模块。类名越精确,影响越小;类名越上层,日志量可能越大。排查调度问题时,通常会关注 ResourceManager 和调度器相关类;排查 Container 启动问题时,更应该看 NodeManager 侧日志,而不是只改 RM 的日志级别。命令能调日志级别,但真正读日志时仍要回到对应服务的日志文件。
4.3 schedulerconf:动态调度器配置
yarn schedulerconf 用来动态更新调度器配置。它支持添加队列、删除队列、更新队列、更新全局配置、获取当前配置等操作:
yarn schedulerconf -getconf
yarn schedulerconf -update "root.default:maximum-capacity=100"
yarn schedulerconf -add "root.etl:capacity=50,maximum-capacity=100"
yarn schedulerconf -remove "root.test"
帮助信息里有一句提示必须注意:
Note: This is an alpha feature, the syntax/options are subject to change, please run at your own risk.
因此它更适合受控环境或明确支持动态队列管理的集群。普通排查里,我会优先用 queue -status、Scheduler 页面和配置文件确认现状;只有在确定集群策略允许动态修改时,才考虑用 schedulerconf 更新。既然它仍带 alpha 提示,就不能默认命令语法和行为长期保持 backward compatibility。
动态更新调度器配置还有一个风险:命令执行成功不等于调度结果符合预期。容量、最大容量、用户限制、ACL、父子队列关系会互相影响。更新队列后最好立即执行:
yarn queue -status <queue>
yarn application -list -appStates RUNNING,ACCEPTED
前者确认队列属性,后者确认应用状态是否按预期变化。对复杂队列树,还应该结合 Scheduler 页面看父队列和子队列的绝对容量、used capacity 和调度器缓存中的队列状态,而不是只看某个叶子队列。
5. 客户端环境与辅助命令
有些问题并不在集群内部,而是出在客户端:配置目录指错、依赖路径不一致、Java 环境不一致、提交命令入口不清楚。下面这组命令适合用来确认“当前这条命令到底运行在什么环境里”。
5.1 classpath、envvars、version:确认客户端环境
很多 YARN 问题表面看是应用失败,实际是客户端环境不一致。比如本地拿错配置目录、classpath 缺少依赖、JAVA_HOME 指向错误、命令使用了另一套 Hadoop 安装目录。下面三个命令专门用来确认环境。
查看版本:
yarn version
输出会包含 Hadoop 版本、编译信息和当前使用的 jar 路径。排查多版本环境时,这个命令比看软链更直接。
查看 classpath:
yarn classpath | tr ':' '\n' | sed -n '1,20p'
输出片段:
/opt/hadoop/etc/hadoop
/opt/hadoop/share/hadoop/common/lib/*
/opt/hadoop/share/hadoop/common/*
/opt/hadoop/share/hadoop/hdfs
/opt/hadoop/share/hadoop/hdfs/lib/*
/opt/hadoop/share/hadoop/mapreduce/*
/opt/hadoop/share/hadoop/yarn
/opt/hadoop/share/hadoop/yarn/lib/*
/opt/hadoop/share/hadoop/yarn/*
查看环境变量:
yarn envvars | sed -n '1,30p'
输出片段:
JAVA_HOME='/usr/lib/jvm/java-11-openjdk-11.0.13.0.8-4.el8_5.x86_64'
HADOOP_YARN_HOME='/opt/hadoop'
YARN_DIR='share/hadoop/yarn'
HADOOP_CONF_DIR='/opt/hadoop/etc/hadoop'
HADOOP_TOOLS_HOME='/opt/hadoop'
如果客户端机器上装了多套 Hadoop,或者脚本由不同用户执行,这三个命令很有用。它们能回答“我现在到底连的是哪套配置、用的是哪套依赖、跑的是哪个 Java”。多 Hadoop 版本并存时,最常见的问题是命令来自一套安装目录,HADOOP_CONF_DIR 指向另一套配置,classpath 又混入第三套 jar,最后表现成提交成功但 AM 或 Container 启动失败。
还有一个全局参数也很实用:
yarn --config /path/to/hadoop-conf application -list
它可以显式指定配置目录。多集群环境里,很多误操作来自 HADOOP_CONF_DIR 指错集群。把 –config 写进排查命令,能减少“我以为连的是测试集群,实际连到生产集群”的风险,也能防止脚本在不同机器上连到不同 cluster。
5.2 jar:提交应用
yarn jar 是提交 Java 应用的入口,形式和 hadoop jar 很像。它本质上是 application submission wrapper:负责启动客户端提交逻辑,真正的资源调度和运行仍然发生在 RM、AM、NM 和 Container 之间。
yarn jar <jar> <main_class> [args...]
Distributed-Shell 示例就是通过 yarn jar 提交的。MapReduce 示例也可以这样提交:
yarn jar /opt/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.4.1.jar pi 16 10000
业务上更常见的是框架自己封装提交命令,例如 Spark 用 spark-submit,Hive、Flink、Tez 也各有入口。但只要应用最终跑在 YARN 上,背后都绕不开 Application、AM、Container、Queue 和日志这些对象。
使用 jar 命令提交应用时,最容易出错的是参数位置。yarn jar 后面先跟 jar 包,再跟主类,再跟应用参数。如果 jar 的 manifest 已经声明了 Main-Class,可以省略主类;否则必须显式写出主类。Distributed-Shell 示例之所以写完整主类,就是为了让提交入口清晰可见。
5.3 top:观察集群使用情况
yarn top 是一个交互式观察工具,可以按用户、队列、应用类型过滤:
yarn top -queues root.default -users root -types YARN
帮助信息里说明它会定期拉取应用、NodeManager 和队列利用率数据。这个命令适合在命令行里快速观察集群压力,但它不是审计工具,也不适合替代监控系统。需要长期趋势时,还是应该看指标系统;需要单个应用证据时,还是应该回到 application 和 logs。
5.4 daemon 类命令
yarn –help 里还能看到一组 daemon 命令:
resourcemanager
nodemanager
proxyserver
router
sharedcachemanager
timelineserver
registrydns
这些命令用于启动对应服务,通常由 start-yarn.sh、systemd、Ambari、Cloudera Manager 或其它运维系统托管。手工执行时要特别小心,避免和现有进程、配置目录、日志目录冲突。单机环境里可以直接启动;生产环境里更推荐通过既有服务管理体系操作。
6. 一套排查顺序
实际排查时,可以按 application、attempt、logs、queue、node 这条主线使用命令。
第一步,确认应用是否存在以及最终状态:
yarn application -list -appStates ALL
yarn application -status <app_id>
如果 Final-State 是 SUCCEEDED,但业务没有产出,就继续看框架日志和输出路径;如果是 FAILED 或 KILLED,先读 Diagnostics。
第二步,确认 AM 和 Attempt:
yarn applicationattempt -list <app_id>
yarn applicationattempt -status <attempt_id>
如果 AM Container 频繁变化,说明 AM 可能在重试。此时不要只看最后一次客户端输出,要看 AM 日志。
第三步,拉取日志:
yarn logs -applicationId <app_id> -am 1
yarn logs -applicationId <app_id> -show_container_log_info
yarn logs -applicationId <app_id> -log_files stderr
AM 日志负责解释应用框架为什么失败,普通 Container 日志负责解释具体任务为什么失败。MapReduce 里经常是某个 Mapper 或 Reducer 报错;Spark 里则可能是 Executor 退出、依赖分发失败或资源申请失败。
第四步,检查资源侧:
yarn queue -status <queue>
yarn node -list
yarn node -status <node_id>
yarn cluster -list-node-labels
yarn nodeattributes -list
如果应用长时间等待,重点看队列容量、队列状态、节点健康、节点标签、资源上限。资源问题不能只盯应用本身。
第五步,必要时做管理刷新或日志级别调整:
yarn rmadmin -refreshQueues
yarn daemonlog -getlevel <host:port> <class>
这一步已经进入管理员操作范围。能用只读命令定位的问题,不要过早执行修改类命令。
再补一组按问题类型划分的命令组合。
应用一直排队:
yarn application -status <app_id>
yarn queue -status <queue>
yarn node -list
yarn node -status <node_id>
应用启动后马上失败:
yarn application -status <app_id>
yarn applicationattempt -list <app_id>
yarn logs -applicationId <app_id> -am 1
任务运行中某个 Container 失败:
yarn logs -applicationId <app_id> -show_container_log_info
yarn logs -applicationId <app_id> -log_files stderr
怀疑客户端连错环境:
yarn version
yarn envvars
yarn classpath | tr ':' '\n' | sed -n '1,20p'
怀疑队列配置改了但没生效:
yarn rmadmin -refreshQueues
yarn queue -status <queue>
这些组合比单条命令更重要。排查不是把所有命令都跑一遍,而是根据对象关系逐步缩小范围:先确认 application,再确认 attempt,再拉 logs,然后检查 queue 和 node。
7. 小结
YARN 命令的重点不是记住多少参数,而是把命令和运行对象对应起来。application 看 YARN Application,applicationattempt 看 AM 运行实例,container 看运行单元,logs 看聚合日志,node 看节点,queue 看队列,rmadmin 和 daemonlog 处理管理动作。Application、Job、Task 不是同一层概念;Container、Process、Executor 也不能混用。对象关系清楚以后,命令自然就能组合起来。
在实际工作中,我会把 yarn application -status、yarn logs、yarn queue -status、yarn node -list 视为最低限度的排查组合。它们能覆盖大多数“任务为什么没跑、为什么失败、为什么没资源、日志在哪里”的问题。更复杂的问题再继续往 Attempt、Container、调度器配置和服务日志里深入。这样使用 YARN 命令,才不会停留在“会列应用、会 kill 任务”的层面,而是能真正支撑一次完整的集群问题定位。