日志聚集

YARN 日志聚集:别一台一台登录服务器查日志了

在 YARN 上跑作业,每个任务分散在不同节点。如果没开日志聚集,排查问题你得这样:

  1. 去 YARN Web UI 看任务跑在哪个节点
  2. SSH 登录那个节点
  3. $HADOOP_HOME/logs/userlogs/ 下面翻日志
  4. 如果任务在不同节点重试过,每个节点都要登一遍

如果那个节点刚好宕机了,日志直接没了。

日志聚集干的事情很简单:任务完成后,自动把日志从各个节点收集起来,存到 HDFS 的一个统一目录里。 你不需要登录任何节点,在 Web UI 或者命令行直接看。

配置:就四个参数

$HADOOP_HOME/etc/hadoop/yarn-site.xml 里加这几行:

<!-- 开启日志聚集功能 -->  
<property>  
  <name>yarn.log-aggregation-enable</name>  
  <value>true</value>  
</property>  

<!-- 日志在 HDFS 中保留 7 天(604800 秒) -->  
<property>  
  <name>yarn.log-aggregation.retain-seconds</name>  
  <value>604800</value>  
</property>  

<!-- 日志清理检查间隔为 1 天(86400 秒) -->  
<property>  
  <name>yarn.log-aggregation.retain-check-interval-seconds</name>  
  <value>86400</value>  
</property>  

<!-- 日志在 HDFS 中的存储路径 -->  
<property>  
  <name>yarn.nodemanager.remote-app-log-dir</name>  
  <value>/var/log/hadoop-yarn/apps</value>  
</property>  

<!-- 日志目录后缀(默认使用用户名) -->  
<property>  
  <name>yarn.nodemanager.remote-app-log-dir-suffix</name>  
  <value>logs</value>  
</property>

配置完要重启 YARN 才生效:

stop-yarn.sh
start-yarn.sh

确认配置生效了

跑一个简单的 MapReduce 任务(比如 WordCount),等它跑完,去 HDFS 里看:

hdfs dfs -ls /var/log/hadoop-yarn/apps/

如果能看到以你用户名命名的目录,说明日志聚集已经生效了。

或者用命令行直接查日志:

yarn logs -applicationId application_xxx_xxx

能输出日志内容,就说明配置成功了。

日志存放结构

日志上传到 HDFS 后,目录结构是这样的:

/var/log/hadoop-yarn/apps/
└── <用户名>/
    └── logs/
        └── <application_id>/
            ├── <节点1>/
            │   ├── stdout
            │   ├── stderr
            │   └── syslog
            └── <节点2>/
                ├── stdout
                ├── stderr
                └── syslog

每个节点单独一个目录,一个应用的所有节点日志都汇聚在一起。不用再登录各个节点去找了。

怎么查日志

方式1:Web UI

  1. 打开 YARN Web UI:http://<ResourceManager节点>:8088
  2. 找到你的应用,点击 Application ID
  3. Logs 链接

方式2:命令行

# 查整个应用的所有日志
yarn logs -applicationId application_1620000000000_0001

# 只查某个容器的日志
yarn logs -applicationId application_1620000000000_0001 -containerId container_xxx

# 只查某个节点的日志
yarn logs -applicationId application_1620000000000_0001 -nodeId node01

日志是怎么上传的

整个流程分四步:

  1. 任务运行时:日志先写在本地的 $HADOOP_HOME/logs/userlogs/<application_id>/<container_id>/ 目录里
  2. 任务完成后:NodeManager 检测到容器结束,把本地日志打包上传到 HDFS
  3. 上传成功后:NodeManager 清理本地的临时日志(默认保留一段时间,可以配置)
  4. 过期清理:ResourceManager 定期检查 HDFS 上的日志,超过保留时间的自动删除

关键点:上传是在任务完成后进行的。 如果任务还在跑,日志还没上传,这时候去 HDFS 里查不到。

几个常见问题和排查方法

问题1:任务跑完了一直看不到日志

可能原因:日志上传还没完成(大任务的日志打包需要时间),或者上传失败了。

查 NodeManager 日志:

tail -f $HADOOP_HOME/logs/yarn-<user>-nodemanager-<node>.log | grep -i aggregation

看有没有上传相关的报错。

问题2:日志上传失败,提示权限不足

NodeManager 用户没有 HDFS 目录的写权限。

hdfs dfs -chmod -R 777 /var/log/hadoop-yarn/apps

或者在配置里换一个有权限的目录。

问题3:日志保留时间不生效

检查 yarn.log-aggregation.retain-secondsyarn.log-aggregation.retain-check-interval-seconds 是不是都配了。检查间隔太大(比如默认 -1),清理任务一直不触发。

问题4:日志太多占满 HDFS 空间

  • 缩短保留时间(比如从 7 天改到 3 天)
  • 开启压缩,减少每个日志的体积:
<property>
  <name>yarn.nodemanager.log-aggregation.compression-type</name>
  <value>gz</value>
</property>
  • 定期检查日志目录大小:
hdfs dfs -du -h /var/log/hadoop-yarn/apps

几个小建议

1. 生产环境一定开日志聚集

不开的话,节点宕机日志就没了,排查问题全靠运气。

2. 保留时间不要设太长

7 天足够。时间太长 HDFS 空间扛不住,时间太短(比如 1 天)可能还没排查完日志就被清了。

3. 确认 HDFS 目录权限

yarn.nodemanager.remote-app-log-dir 指定的目录,确保 YARN 用户有写入权限。不然日志上传会失败,但 YARN 不会报明显错误,只在 NodeManager 日志里有记录。