0%

日志聚集

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

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

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

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

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

配置:就四个参数

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!-- 开启日志聚集功能 -->  
<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 才生效:

1
2
stop-yarn.sh
start-yarn.sh

确认配置生效了

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

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

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

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

1
yarn logs -applicationId application_xxx_xxx

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

日志存放结构

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

1
2
3
4
5
6
7
8
9
10
11
12
/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:命令行

1
2
3
4
5
6
7
8
# 查整个应用的所有日志
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 日志:

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

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

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

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

1
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 天)
  • 开启压缩,减少每个日志的体积:
1
2
3
4
<property>
<name>yarn.nodemanager.log-aggregation.compression-type</name>
<value>gz</value>
</property>
  • 定期检查日志目录大小:
1
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 日志里有记录。

欢迎关注我的其它发布渠道