当前位置: 首页 > news >正文

Yarn Application 日志总结

前言

总结整理 Yarn 任务运行日志。主要解决:

  • Web UI 查看运行中 yarn 任务对应的所有 container 的日志
  • Web Ui 查看已经结束的历史 yarn 任务对应的 所有 container 的日志
  • 任务异常结束后,如果日志聚合失败,保留 NodeManager 本地日志

版本

  • Flink 1.15.3
  • Hadoop 3.4.1、3.1.4

运行中的日志

命令行

在命令中查看:

yarn logs -applicationId <application ID>

Web UI

Resource Manager Web UI 默认端口:8088
3.4.1 和 3.1.4 的 Web UI 界面稍微有所不同:
3.4.1:

3.1.4:

点击 Application ID,进到详情页,这里只能看 ApplicationMaster 的日志,对应 Flink 则为 JobManager,点击 jobmanager.log 就可以查看详细的JobManager日志。
对应地址:http://nodemanagerIp:8042/node/containerlogs/container_1753359030665_0001_01_000001/root

其他 container 的日志对应 flink 的 taskmanager :点击 Attempt Id, 进到 Attempt 详情页,就可以看其他 container的日志了,containerId 是和 attemptId 绑定的,一个yarn 任务如果有失败重试的话会有多个 attemptId。
对应地址:http://nodemanagerIp:8042/node/containerlogs/container_1753359030665_0001_01_000002/root


当然运行中的日志也可以通过 flink web ui 查看:resourceMangerIp:8088/proxy/applicationId

日志存储路径

本地

运行中任务日志存储在本地,由参数 yarn.nodemanager.log-dirs 决定,比如:

<property><name>yarn.nodemanager.log-dirs</name><value>/indata/disk_0/nodemanager</value>
</property>
  • 那么本地路径为 /indata/disk_0/nodemanager/applicationId
  • 一个 yarn 任务有多个 container ,不同的 container 可能在相同的 nodemanager 也可能在不同的 nodemanager ,本地日志需要去 container 对应的 nodemanager 机器查看
  • 如果运行中的任务对应的本地日志文件被意外删除,那么无论通过命令行还是 Web UI 都将看不到日志了

聚合

相关参数:

<!-- 开启日志聚合 -->
<property><name>yarn.log-aggregation-enable</name><value>true</value>
</property>
<!-- 日志聚合HDFS目录 -->
<property><name>yarn.nodemanager.remote-app-log-dir</name><value>/app-logs</value>
</property>

yarn 任务结束后会将本地日志聚合到对应的 hdfs 路径下,这里的路径为 /app-logs ,其实在任务运行中,该任务对应的路径已经存在了,只不过文件为空,大小为0

历史任务日志

上面提到了 yarn 任务结束后会将本地日志聚合到对应的 hdfs 路径下 ,所以我们在任务结束后也可以查看任务日志

命令行

在命令中查看:

yarn logs -applicationId <application ID>

Web UI

与运行中的任务有两个不同点:一个是点击logs 后 如果没有配置 yarn.log.server.url ,访问地址一样,但是会提示需要配置 Log Server url ,看不到任何日志 ,

yarn.log.server.url 配置参数:

  <property><name>yarn.log.server.url</name><value>http://JobHistoryServerIp:19888/jobhistory/logs</value></property>

这里的 JobHistoryServerIp:19888 是 mapreduce.jobhistory.webapp.address 对应的地址:

mapred-site.xml

  <!-- 配置 MapReduce JobHistory Server HTTP地址, 默认端口19888 --><property><name>mapreduce.jobhistory.webapp.address</name><value>0.0.0.0:19888</value></property>

所以还要在对应节点启动 MapReduce JobHistory Server ,启动命令:

mapred --daemon start historyserver

这样再点击 logs ,就可以看到对应的日志了,但是地址已经变了:http://JobHistoryServerIp:19888/jobhistory/logs/nodemanagerIp:40879/container_1753359030665_0001_01_000001/container_1753359030665_0001_01_000001/root

另一个不同点是,任务结束后 Attempt 详情页是看不到 container 的,也就是Attempt 详情页只能看到运行中的 container,这样我们就没法直接看另一个 container 对应的 taskmanager 日志了。

那么该怎么看呢?其实只要我们知道对应的 nodemanagerIp、port、containerId 就可以了,最开始查到如下命令:

yarn container -list <Attempt ID>

但是他只能查看运行中的 container

最终通过命令:

yarn logs -applicationId <Application Id> -show_application_log_info

这样根据返回的信息,就可以得到taskmanager 对应的历史地址 url了。

日志文件

对于历史任务,默认参数下(已开启日志聚合),在任务结束时会将本地日志聚合到HDFS路径下,本地的日志文件会立马删除。

其他参数

保留时间

<!-- 聚合日志保留时间,默认 -1 即不删除 -->
<property><name>yarn.log-aggregation.retain-seconds</name><value>2592000</value>
</property><!-- nodemanager 任务完成后本地日志保留时间,默认 0 即不保留 -->
<!-- 有时会遇到任务异常结束后,日志聚合没成功,这时就需要保留本地日志,方便分析原因 -->
<property><name>yarn.nodemanager.delete.debug-delay-sec</name><value>86400</value>
</property><!-- 保留用户日志的时长(以秒为单位),但需注意该参数仅在日志聚合功能关闭时才适用 -->
<property><name>yarn.nodemanager.log.retain-seconds</name><value>86400</value>
</property>

日志路径

<property><description>运行中的任务日志对应的本地存储路径</description><name>yarn.nodemanager.log-dirs</name><value>/indata/disk_0/nodemanager</value>
</property><property><description>Where to aggregate logs to. 默认值 /tmp/logs</description><name>yarn.nodemanager.remote-app-log-dir</name><value>/app-logs</value>
</property><property><description>The remote log dir will be created at {yarn.nodemanager.remote-app-log-dir}/${user}/{thisParam}</description><name>yarn.nodemanager.remote-app-log-dir-suffix</name><value>logs</value>
</property><property><name>yarn.log-aggregation.TFile.remote-app-log-dir-suffix</name><value>logs</value>
</property>  

这里主要是想总结一下聚合日志路径格式:
在没有配置 yarn.log-aggregation.TFile.remote-app-log-dir-suffix 时:

Hadoop 3.1.4 : ${yarn.nodemanager.remote-app-log-dir}/${user}/${yarn.nodemanager.remote-app-log-dir-suffix}-tfile/${appId}
Hadoop 3.4.1 : ${yarn.nodemanager.remote-app-log-dir}/${user}/bucket-${yarn.nodemanager.remote-app-log-dir-suffix}-tfile/${bucketDir}/${appId}
HDP 3.1.1.3.1.0.0-78 : ${yarn.nodemanager.remote-app-log-dir}/${user}/${yarn.nodemanager.remote-app-log-dir-suffix}/${appId}

对应到上面的参数:
Hadoop 3.1.4 : /app-logs/${user}/logs-tfile/${appId}
Hadoop 3.4.1 : /app-logs/bucket-${user}/logs-tfile/${appId}
HDP 3.1.1.3.1.0.0-78 :/app-logs/${user}/logs/${appId}

可以看到开源的 3.1.4 版本在 yarn.nodemanager.remote-app-log-dir-suffix 后面加了 -tfile、开源的 3.4.1 版本又加了 bucket-,但我不喜欢加 tfile这种格式,更喜欢 HDP 的格式,于是我搜了一下 3.1.4 查看为啥会加默认加 -tfile,最后发现通过添加 yarn.log-aggregation.TFile.remote-app-log-dir-suffix 就可以去掉 -tfile 从而实现我想要的格式效果。

注意:修改日志路径不仅要重启 Yarn,还要重启 MapReduce JobHistory Server

相关源码

3.1.4 版本:



public static final String YARN_PREFIX = "yarn.";
public static final String LOG_AGGREGATION_REMOTE_APP_LOG_DIR_FMT= YARN_PREFIX + "log-aggregation.%s.remote-app-log-dir";/** Prefix for all node manager configs.*/
public static final String NM_PREFIX = "yarn.nodemanager.";
public static final String NM_REMOTE_APP_LOG_DIR_SUFFIX = NM_PREFIX + "remote-app-log-dir-suffix";

主要逻辑就是先判断有没有设置 yarn.log-aggregation.TFile.remote-app-log-dir-suffix 如果有的话,则 remoteRootLogDirSuffix 取值为 ${yarn.log-aggregation.TFile.remote-app-log-dir-suffix} ,如果没有则 remoteRootLogDirSuffix 取值为 ${yarn.nodemanager.remote-app-log-dir-suffix}-tfile

3.4.1 版本因为多了一层 ${bucketDir} ,所以当设置了 yarn.log-aggregation.TFile.remote-app-log-dir-suffix 其对应的值为 bucket-${yarn.log-aggregation.TFile.remote-app-log-dir-suffix} ,对应代码:

  public static Path getRemoteAppLogDir(Path remoteRootLogDir,ApplicationId appId, String user, String suffix) {return new Path(getRemoteBucketDir(remoteRootLogDir, user, suffix,appId), appId.toString());}public static Path getRemoteBucketDir(Path remoteRootLogDir, String user,String suffix, ApplicationId appId) {int bucket = appId.getId() % 10000;String bucketDir = String.format("%04d", bucket);return new Path(getRemoteLogSuffixedDir(remoteRootLogDir,user, suffix), bucketDir);}public static Path getRemoteLogSuffixedDir(Path remoteRootLogDir,String user, String suffix) {suffix = getBucketSuffix() + suffix;return new Path(getRemoteLogUserDir(remoteRootLogDir, user), suffix);}public static String getBucketSuffix() {return BUCKET_SUFFIX;}private static final String BUCKET_SUFFIX = "bucket-";
效果截图

3.1.4 :

3.4.1 :

NodeManager 端口

<property><description>Ephemeral ports (port 0, which is default) cannot be used for the NodeManager's RPC server specified via yarn.nodemanager.address as it can make NM use different ports before and after a restart. This will break any previously running clients that were communicating with the NM before restart. Explicitly setting yarn.nodemanager.address to an address with specific port number (for e.g 0.0.0.0:45454) is a precondition for enabling NM restart.临时端口(默认端口0)不能用于通过yarn.nodemanager.address指定的NodeManager的RPC服务器,因为这会导致NM在重启前后使用不同的端口。这将中断重启前与NM通信的任何正在运行的客户端。将yarn.nodemanager.address显式设置为具有特定端口号(例如0.0.0.0:45454)的地址是启用NM重启的先决条件。</description> <name>yarn.nodemanager.address</name><value>0.0.0.0:45454</value>
</property>

默认参数时:

<property><description>The address of the container manager in the NM.</description><name>yarn.nodemanager.address</name><value>${yarn.nodemanager.hostname}:0</value>
</property><property><description>The hostname of the NM.</description><name>yarn.nodemanager.hostname</name><value>0.0.0.0</value>
</property>

除了上面说的会中断重启前与NM通信的任何正在运行的客户端,还会导致不同的 yarn 任务历史日志对应的端口不同:

这样访问起来比较麻烦,可以通过配置固定端口号来解决这个问题。

http://www.dtcms.com/a/315831.html

相关文章:

  • 美化一下达梦grant授权说明
  • 蓝桥杯----DS1302实时时钟
  • 私有云盘新体验:FileRise在cpolar的加持下如何让数据管理更自由?
  • 对话访谈|盘古信息×易景科技:宜宾OEM+ODM 标杆,如何规划数字化转型?
  • MySQL Redo Log浅析
  • 无刷电机控制 - STM32F405+CubeMX+HAL库+SimpleFOC06,速度闭环控制(没电流环)
  • 人工智能领域、图欧科技、IMYAI智能助手2025年7月更新月报
  • SOLIDWORKS 买断许可和订阅许可的资金流影响分析-代理商硕迪科技
  • 江协科技STM32学习笔记1
  • Augmodo AI:零售门店智能货架管理平台
  • 复制网页文字到Word、WPS文字?选中后直接拖放
  • MousePlus鼠标右键增强工具v5.5.25,支持鼠标轮盘功能
  • mac前端环境安装
  • HTTP 与 HTTPS 的区别深度解析:从原理到实践
  • 实战教程 node js 实现上传xls文件批量导入到数据库 解析导入
  • 微服务—Gateway
  • 分发饼干(贪心算法)
  • linux服务器上word转pdf后乱码问题
  • HTTP性能优化实战:解决高并发场景下的连接瓶颈与延迟问题
  • 【实时Linux实战系列】实时传感器数据融合技术
  • 原生CSS vs LESS:样式表语言的进化之旅
  • 阿里云招Java研发咯
  • ORACLE多表查询
  • 07-一般的树
  • Opencv: 不同函数所支持的Mat类型汇总
  • C语言——编译和链接
  • 【RabbitMQ】高级特性—持久性、重试机制详解
  • GO如何设置代理
  • Python 中的 Matplotlib:安装与使用指南
  • 雷达水位监测站:让水位监测变得轻松又可靠!