0%

日志详解

一. Hadoop 日志存放路径详解

Hadoop的日志大致可以分为两大类,且这两类的日志存放的路径是不一样的。本文基于Hadoop 2.x 版本进行说明的。

  1. Hadoop 系统服务输出的日志
  2. Mapreduce 程序输出来的日志 ( 作业运行日志 、任务运行日志 (Container 日志))

在 Hadoop 2.0 中,Mapreduce 程序的日志包含两部分,作业运行日志任务运行日志(Container 日志)

1.1 Hadoop系统服务输出的日志

诸如 NameNode、DataNode、ResourceManage 等系统自带的服务输出来的日志默认是存放在 ${HADOOP_HOME}/logs目录下。比如 resourcemanager 的输出日志为 yarn-${USER}-resourcemanager-${hostname}.log

  • yarn 指的就是该日志的属性即为 YARN,其他类似的有 mapred、hadoop 等
  • ${USER}s 是指启动 resourcemanager 进程的用户
  • resourcemanager 就是指明 resourcemanager 进程,其他类似的有 namenode、zkfc、historyserver 等
  • ${hostname} 是 resourcemanager 进程所在机器的 hostname

当日志到达一定的大小(可以在 ${HADOOP_HOME}/etc/hadoop/log4j.properties 文件中配置)将会被切割出一个新的文件,切割出来的日志文件名类似 yarn-${USER}-resourcemanager-${hostname}.log.数字 的形式,后面的数字越大,代表日志越旧。在默认情况下,只保存前 20 个日志文件,比如下面:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[hadoop@master logs]$ ll
总用量 7360356
-rw-rw-r--. 1 hadoop hadoop 6251772 10月 16 13:59 hadoop-hadoop-datanode-devhost21.log
-rw-rw-r--. 1 hadoop hadoop 722 10月 16 10:52 hadoop-hadoop-datanode-devhost21.out
-rw-rw-r--. 1 hadoop hadoop 722 9月 17 15:09 hadoop-hadoop-datanode-devhost21.out.1
-rw-rw-r--. 1 hadoop hadoop 722 9月 15 23:10 hadoop-hadoop-datanode-devhost21.out.2
-rw-rw-r--. 1 hadoop hadoop 722 8月 17 20:34 hadoop-hadoop-datanode-devhost21.out.3
-rw-rw-r--. 1 hadoop hadoop 151078937 2月 8 19:16 hadoop-hadoop-datanode-master.log
-rw-rw-r--. 1 hadoop hadoop 268479664 12月 8 10:00 hadoop-hadoop-datanode-master.log.1
-rw-rw-r--. 1 hadoop hadoop 268471403 11月 14 11:34 hadoop-hadoop-datanode-master.log.2
-rw-rw-r--. 1 hadoop hadoop 268439864 11月 8 08:30 hadoop-hadoop-datanode-master.log.3
-rw-rw-r--. 1 hadoop hadoop 268435710 8月 17 19:00 hadoop-hadoop-datanode-master.log.4
-rw-rw-r--. 1 hadoop hadoop 268445084 8月 16 21:33 hadoop-hadoop-datanode-master.log.5
-rw-rw-r--. 1 hadoop hadoop 722 1月 4 14:09 hadoop-hadoop-datanode-master.out
-rw-rw-r--. 1 hadoop hadoop 722 12月 20 10:49 hadoop-hadoop-datanode-master.out.1
-rw-rw-r--. 1 hadoop hadoop 722 12月 18 16:13 hadoop-hadoop-datanode-master.out.2
-rw-rw-r--. 1 hadoop hadoop 722 10月 30 15:20 hadoop-hadoop-datanode-master.out.3
-rw-rw-r--. 1 hadoop hadoop 722 10月 30 15:17 hadoop-hadoop-datanode-master.out.4
-rw-rw-r--. 1 hadoop hadoop 722 10月 30 13:14 hadoop-hadoop-datanode-master.out.5

1.2 配置 Hadoop 系统服务日志

1. 配置 log4j 日志的属性参数

比如 resourcemanager(在 ${HADOOP_HOME}/etc/hadoop/log4j.properties):

1
2
3
4
5
6
7
8
9
10
11
log4j.logger.org.apache.hadoop.yarn.server.resourcemanager.RMAppManager
$ApplicationSummary=${yarn.server.resourcemanager.appsummary.logger}
log4j.additivity.org.apache.hadoop.yarn.server.resourcemanager
.RMAppManager$ApplicationSummary=false
log4j.appender.RMSUMMARY=org.apache.log4j.RollingFileAppender
log4j.appender.RMSUMMARY.File=${hadoop.log.dir}/
${yarn.server.resourcemanager.appsummary.log.file}
log4j.appender.RMSUMMARY.MaxFileSize=256MB(多大切割日志)
log4j.appender.RMSUMMARY.MaxBackupIndex=20(说明保存最近20个日志文件)
log4j.appender.RMSUMMARY.layout=org.apache.log4j.PatternLayout
log4j.appender.RMSUMMARY.layout.ConversionPattern=%d{ISO8601} %p %c{2}: %m%n

2. 配置 resourcemanager 日志存放路径

${HADOOP_HOME}/etc/hadoop/yarn-env.sh 文件中

1
2
3
4
# default log directory & file
if [ "$YARN_LOG_DIR" = "" ]; then
YARN_LOG_DIR="$HADOOP_YARN_HOME/logs"
fi

只需要修改 YARN_LOG_DIR 的值,这时候,yarn 相关的日志记录都将存放在你配置的目录下。

二. 历史服务器 (JobHistory Server)

MapReduce 的 JobHistory Server,这是一个独立的服务,可通过 web UI 展示历史作业日志,之所以将其独立出来,是为了减轻 ResourceManager 负担。JobHistory Server 将会分析作业运行日志,并展示作业的启动时间、结束时间、各个任务的运行时间,各种Counter数据等,并产生一个指向作业和任务日志的链接,其默认端口号为 19888。通常可以启动在一台独立的机器上

2.1 历史服务器配置

你需在 mapred-site.xml 中对其进行配置

1
2
3
4
5
6
7
8
9
<property>
<name>mapreduce.jobhistory.address</name>
<value>0.0.0.0:10020</value>
</property>

<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>0.0.0.0:19888</value>
</property>

上面的参数是在 mapred-site.xml 文件中进行配置,mapreduce.jobhistory.address 和 mapreduce.jobhistory.webapp.address 默认的值分别是 0.0.0.0:10020 和 0.0.0.0:19888,大家可以一定要根据自己的情况进行相应的配置,最好别用默认的 0.0.0.0 ,参数的格式是 host:port。

在 Hadoop 历史服务器的 WEB UI 上最多显示 20000 个历史的作业记录信息;其实我们可以在 mapred-site.xml 文件中通过下面的参数进行配置,然后重启一下 Hadoop jobhistory 即可。

1
2
3
4
<property>
<name>mapreduce.jobhistory.joblist.cache.size</name>
<value>20000</value>
</property>

2.2 关于 HA 模式下的历史服务器配置的结论

笔者的集群是 HA 模式的( HDFS 和 ResourceManager HA)。在 ” Hadoop-2.5.0-cdh5.3.2 HA 安装" 中详细讲解了关于 HA 模式的搭建,这里就不再赘述。但网上直接将关于 HA 模式下的历史服务器的配置资料却很少。

笔者在思考,如果配置在 mapred-site.xml 中就设置一台历史服务器,那么当这台机器挂了,那么能不能有另一台机器来承担历史服务器的责任,也就是笔者理想当然的 jobhistory server HA 模式。后面经过各自尝试,得出来的结论是笔者我太年轻了,概念没有搞懂,先总结如下:

  • 历史服务器是个独立的服务,其不会受到 namenode 和 resourcemanager 的 active/standby 切换所带来的影响
  • 当历史服务器突然失效了,那些日志文件依旧存在 HDFS 上。当历史服务器又恢复正常,还是能看到在历史服务器失效期间的运行日志
  • 可以很简单地把历史服务器当成是存在 HDFS 上日志文件的 Web 浏览器。当且仅当历史服务器启动后,才可以通过 Web 查看,比如 http://10.6.3.43:19888/jobhistory
  • 实际上,每台机器的 MapReduce 历史服务器的配置可以不同,当在哪台机器上执行程序时,那么所指向的历史服务器地址其实就是 mapred-site.xml 文件中 mapreduce.jobhistory.webapp.address 配置参数所指定的那台机器

所以 Hadoop HA 模式下的历史服务器配置和非 HA 模式是一样样的,如果你自作聪明(比如笔者),在 mapred-site.xml 文件中,添加了两个运行 namenode(resourcemanager) 进程的主备节点的主机名(或IP地址)。

但是真正在两台主机上同时启动历史服务器进程时,会报如下的类似错误:

INFO org.apache.hadoop.http.HttpServer2: HttpServer.start() threw a non Bind IOException
77504 java.net.BindException: Port in use: master52:19888
Caused by: java.net.BindException: Cannot assign requested address
INFO org.apache.hadoop.service.AbstractService: Service HistoryClientService failed in state STARTED; cause: org.apache.hadoop.yarn.webapp.WebAppException: Error starting http server
INFO org.apache.hadoop.util.ExitUtil: Exiting with status -1

原因就是端口被占用了,很明显如果不改变端口,有且仅有一个 历史服务器成功启动,且启动的那个服务器是在 mapred-site.xml 文件中设置位置最下面的那个,及后面的配置参数将覆盖前一个配置参数。就算改变端口也没卵用…

Note:以上这些是笔者一边操作,一边对比总结,有些结论未必是正确的,还请各位指正…

2.3 启动历史服务器

配置完上述的参数之后,重新启动 Hadoop jobhistory,这样我们就可以在 mapreduce.jobhistory.webapp.address 参数配置的主机上对 Hadoop 历史作业情况经行查看。

只能在 mapred-site.xml 文件中 mapreduce.jobhistory.webapp.address 配置参数所指定的那台机器上执行:

1
sbin/mr-jobhistory-daemon.sh start jobhistoryserver

这样我们就可以在相应机器的 19888 端口上打开历史服务器的 WEB UI 界面。可以查看已经运行完的作业情况。且在 HDFS 上可以看到如下目录:

1
2
3
4
5
6
/tmp
/tmp/hadoop-yarn
/tmp/hadoop-yarn/staging
/tmp/hadoop-yarn/staging/history
/tmp/hadoop-yarn/staging/history/done
/tmp/hadoop-yarn/staging/history/done_intermediate

三. 作业运行日志

3.1 作业运行日志概念

作业运行由 MRAppMaster(MapReduce 作业的 ApplicationMaster)产生,详细记录了作业启动时间、运行时间,每个任务启动时间、运行时间、Counter 值等信息,与 Hadoop 1.0 中的 JobHistory 日志是基本一致。MapReduce 作业的 ApplicationMaster 也运行在 Container 中,且是编号为 000001 的 Container,比如 container_1385051297072_0001_01_000001,它自身可认为是一个特殊的 task,因此,也有自己的运行日志,该日志与 Map Task 和 Reduce Task 类似,但并不是前面介绍的”作业运行日志”。

ApplicationMaster 产生的作业运行日志举例如下,日志采用 apache avro(作为日志存储格式是 Hadoop 2.0 唯一使用到 Avro 的地方)工具,以 json 的格式保存:

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
30
31
32
33
34
35
36
37
38
39
40
41
{
"type":"JOB_SUBMITTED",
"event":
{"org.apache.hadoop.mapreduce.jobhistory.JobSubmitted":
{"jobid":"job_1385051297072_0002″,
"jobName":"QuasiMonteCarlo",
"userName":"yarn",
"submitTime":1385393834983,
"jobConfPath":"hdfs://hadoop-test/tmp/hadoop-yarn/staging/yarn/.staging/job_1385051297072_0002/job.xml",
"acls":{},
"jobQueueName":"default",
"workflowId":"",
"workflowName":"",
"workflowNodeName":"",
"workflowAdjacencies":"",
"workflowTags":""
}
}
}
{
"type":"JOB_INITED",
"event":
{"org.apache.hadoop.mapreduce.jobhistory.JobInited":
{"jobid":"job_1385051297072_0002″,
"launchTime":1385393974505,
"totalMaps":8,
"totalReduces":1,
"jobStatus":"INITED",
"uberized":false}
}
}
{
"type":"JOB_INFO_CHANGED",
"event":
{"org.apache.hadoop.mapreduce.jobhistory.JobInfoChange":
{"jobid":"job_1385051297072_0002″,
"submitTime":1385393834983,
"launchTime":1385393974505
}
}
}

3.2 作业运行日志配置

历史作业的记录里面包含了一个作业用了多少个 Map、用了多少个 Reduce、作业提交时间、作业启动时间、作业完成时间等信息;这些信息对分析作业是很有帮助的,我们可以通过这些历史作业记录得到每天有多少个作业运行成功、有多少个作业运行失败、每个队列作业运行了多少个作业等很有用的信息。这些历史作业的信息是通过下面的信息配置的:

在 mapred-site.xml 文件中进行配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<property>
<name>mapreduce.jobhistory.done-dir</name>
<value>${yarn.app.mapreduce.am.staging-dir}/history/done</value>
</property>

<property>
<name>mapreduce.jobhistory.intermediate-done-dir</name>
<value>${yarn.app.mapreduce.am.staging-dir}/history/done_intermediate</value>
</property>

<property>
<name>yarn.app.mapreduce.am.staging-dir</name>
<value>/tmp/hadoop-yarn/staging</value>
</property>

3.3 作业运行日志产生过程

1. 启动作业的 ApplicationMaster 并写日志至 HDFS

  • ResourceManager 启动作业的 ApplicationMaster
  • ApplicationMaster 运行过程中,将日志写到 ${yarn.app.mapreduce.am.staging-dir}/yarn/.staging/job_XXXXX_XXX/
  • 参数 yarn.app.mapreduce.am.staging-dir 的默认值是 /tmp/hadoop-yarn/staging
  • 该目录下将存在3个文件,分别是以 “.jhist“、”.summary” 和 “.xml” 结尾的文件,分别表示作业运行日志、作业概要信息和作业配置属性,其中,作业概要信息只有一句话,举例如下:
1
2
3
4
5
jobId=job_1385051297072_0002,submitTime=1385393834983,launchTime=1385393974505,
firstMapTaskLaunchTime=1385393976706,firstReduceTaskLaunchTime=1385393982581,
finishTime=1385393985417,resourcesPerMap=1024,resourcesPerReduce=1024,
numMaps=8,numReduces=1,user=yarn,queue=default,status=SUCCEEDED,
mapSlotSeconds=47,reduceSlotSeconds=5,jobName=QuasiMonteCarlo

2. HDFS 内转移历史运行日志

  • 所有任务运行完成后,意味着,该作业运行完成
  • 此时 ApplicationMaster 将三个文件拷贝到 ${ mapreduce.jobhistory.intermediate-done-dir}/${username} 目录下,拷贝后的文件名后面添加 "_tmp"
  • 其中 mapreduce.jobhistory.intermediate-done-dir 默认值是 ${yarn.app.mapreduce.am.staging-dir}/history/done_intermediate
  • ApplicationMaster 将拷贝完成的三个文件重新命名成 “.jhist”、”.summary” 和 “.xml” 结尾的文件(去掉 "_tmp"

3. 周期转移 done_intermediate 中的日志文件到 done 目录

  • 周期性扫描线程定期将 done_intermediate 的日志文件转移到 done 目录
  • 通过参数 mapreduce.jobhistory.done-dir 配置,默认值为 ${yarn.app.mapreduce.am.staging-dir}/history/done)
  • 同时删除 “.summary” 文件(该文件中的信息,.jhist 文件中都有)
  • ApplicationMaster 移除 ${yarn.app.mapreduce.am.staging-dir}/yarn/.staging/job_XXXXX_XXX/ 目录

四. 任务运行日志 (Container 日志)

4.1 Container 日志基本概念

默认情况下,任务运行日志 (Container 日志) 产只会存放在各 NodeManager 的本地磁盘上,且 NodeManager 将日志保存到 yarn.nodemanager.log-dirs 下 ,该属性缺省值为 ${yarn.log.dir}/userlogs,也就是 Hadoop 安装目录下的 logs/userlogs 目录中,通常为了分摊磁盘负载,我们会为该参数设置多个路径。

需要注意的是,ApplicationMaster 的自身的日志也存放在该路目下,因为它也运行在 Container 之中,是一个特殊的 task。举例如下,其中,第一个是某个作业的 ApplicationMaster 日志(编号是000001)。且里面包含 stderr 、stdout 、 syslog 三个文件。

1
2
3
4
5
container_1449861199315_0036_01_000001
container_1449861199315_0036_01_000023
container_1449861199315_0036_01_000061
container_1449861199315_0036_01_000099
container_1449861199315_0036_01_000137

因为默认情况下,任务运行日志产只会存放在各 NodeManager 的本地磁盘上,而一个集群又有多个 NodeManager,将作业和任务日志存放在各个节点上肯定不便于统一管理和分析,为此,我们可以启用日志聚集功能。打开该功能后,各个任务运行完成后,会将生成的日志推送到 HDFS 的一个目录下,以便集中管理和分析(之前的并不会立即删除,在 HDFS 上,每个任务产生的三个文件,即 syslog、stderr 和 stdout 将合并一个文件,并通过索引记录各自位置)。

4.2 不开启日志聚合时的日志配置

Container 日志包含 ApplicationMaster 日志和普通 Task 日志等信息。默认情况下,这些日志信息是存放在 ${HADOOP_HOME}/logs/userlogs 目录下(在那些 NodeManager 的机子上),我们可以通过下面的配置进行修改:

1
2
3
4
5
6
7
8
9
10
11
<property>
<description>
Where to store container logs. An application's localized log directory
will be found in ${yarn.nodemanager.log-dirs}/application_${appid}.
Individual containers' log directories will be below this, in
directories named container_{$contid}. Each container directory will
contain the files stderr, stdin, and syslog generated by that container.
</description>
<name>yarn.nodemanager.log-dirs</name>
<value>${yarn.log.dir}/userlogs</value>
</property>

4.3 开启日志聚合时的配置参数

日志聚集是 YARN 提供的日志中央化管理功能,它能将运行完成的 Container/ 任务日志上传到 HDFS 上,从而减轻 NodeManager 负载,且提供一个中央化存储和分析机制。默认情况下,Container/ 任务日志存在在各个 NodeManager 上,如果启用日志聚集功能需要额外的配置。

yarn-site.xml 中设置

1. yarn.log-aggregation-enable

  • 参数解释:是否启用日志聚集功能。
  • 默认值:false

2. yarn.log-aggregation.retain-seconds

  • 参数解释:在 HDFS 上聚集的日志最多保存多长时间。
  • 默认值:-1

3. yarn.log-aggregation.retain-check-interval-seconds

  • 参数解释:多长时间检查一次日志,并将满足条件的删除,如果是 0 或者负数,则为上一个值的 1/10。
  • 默认值:-1

4. yarn.nodemanager.remote-app-log-dir

  • 参数解释:当应用程序运行结束后,日志被转移到的HDFS目录(启用日志聚集功能时有效)
  • 默认值:/tmp/logs

5. yarn.nodemanager.remote-app-log-dir-suffix

  • 参数解释:远程日志目录子目录名称(启用日志聚集功能时有效)
  • 默认值:日志将被转移到目录 ${yarn.nodemanager.remote-app-log-dir}/${user}/${thisParam}

4.4 其他配置指导

  • 远端的聚合日志的地址的文件夹权限应该是 1777, ${NMUser}${NMGroup} 是所有者和所有组.
  • 每个应用层次的日志的权限是 770, 但是文件夹所有人是应用的提交者, 文件夹的所有群组是 ${NMGroup}, 这样安排可以让应用的提交者能访问到聚合后的日志, 并且${NMGroup}可以访问和修改日志.
  • ${NMGroup} 应该是一个有限访问的群组, 这样才不会造成访问泄露.

五. 扩展知识

5.1 mapred-site.xml 和 yarn-site.xml 的作用

1. yarn-site.xml
yarn-site.xml 是 YARN 相关的配置文件,客户端、ResourceManager 和 NodeManager 需要改配置文件,为了简单,可让这三类节点上的该文件是一致的。

2. Mapred-site.xml
Mapred-site.xml 是 MapReduce 特有的配置文件,在 YARN 中,mapreduce 已经变成了一个客户端编程库,因此只有客户端和 jobhistory server 需要该配置文件,其他节点,比如 resourceManager 和 NodeManager 不需要,除非你们也把这些节点作为客户端提供给用户使用,另外,一定要让客户端和 jobhistory server 上的 mapres-site.xml 一致。

5.2 权限相关配置参数

注意,配置这些参数前,应充分理解这几个参数的含义,以防止误配给集群带来的隐患。另外,这些参数均需要在 yarn-site.xml 中配置。

这里的权限由三部分组成,分别是:

1. 管理员和普通用户如何区分
管理员列表由参数 yarn.admin.acl 指定。

2. 服务级别的权限
比如哪些用户可以向集群提交 ResourceManager 提交应用程序,服务级别的权限是通过配置 hadoop-policy.xml 实现的,这个与 Hadoop 1.0 类似。

3. 队列级别的权限
比如哪些用户可以向队列A提交作业等。队列级别的权限是由对应的资源调度器内部配置的,比如 Fair Scheduler 或者 Capacity Scheduler 等。