【MapReduce】作业调试

2021-09-10 11:26:01 浏览数 (1)

作业调试

History Server开启

因为yarn集群重启之后,作业的历史运行日志和信息就被清理掉了,对于定位历史任务的错误信息很不友好,所以首先开启History Server用于保存所有作业的历史信息。

首先编辑yarn-site.xml文件,开启yarn的日志聚合功能。

代码语言:javascript复制
cd $HADOOP_HOME/etc/hadoop
vim yarn-site.xml

添加的配置如下:

代码语言:javascript复制
  <property>
      <name>yarn.log-aggregation-enable</name>
      <value>true</value>
  </property>
   <property>
	<name>yarn.log-aggregation.retain-seconds</name>
	<value>2592000</value>
  </property>
  <property>
    <name>yarn.log.server.url</name>
    <value>http://node01:19888</value>
  </property>
  <property>
    <name>yarn.nodemanager.remote-app-log-dir</name>
    <value>hdfs://node01:9000/yarn-logs/</value>
  </property>

然后编辑mapred-site.xml文件,添加History-Server基本配置:

代码语言:javascript复制
cd $HADOOP_HOME/etc/hadoop
vim mapred-site.xml

添加的配置如下:

代码语言:javascript复制
  <property>
      <name>mapreduce.jobhistory.address</name>
      <value>node01:10020</value>
  </property>
    <property>
      <name>mapreduce.jobhistory.webapp.address</name>
      <value>node01:19888</value>
  </property>
    <property>
      <name>mapreduce.jobhistory.intermediate-done-dir</name>
      <value>/mr-history/log</value>
  </property>
    <property>
      <name>mapreduce.jobhistory.done-dir</name>
      <value>/mr-history/done</value>
  </property>

因为集群搭建脚本中已经添加了前2个配置项,所以只需要添加后2个即可。

配置的具体含义如下:

然后重启集群,使配置生效:

代码语言:javascript复制
stop-all.sh
start-all.sh

启动history-server:

代码语言:javascript复制
mr-jobhistory-daemon.sh start historyserver

此时,可以在hdfs中看到HistoryServer的存储目录就被创建出来了。

于是,现在历史作业的运行信息就可以被保留下来了,但前提是在history-server在启动的情况下。

辅助脚本

作业清理&提交

MapReduce任务在集群中提交时,如果报错,则需要清理环境,删除jar包和中间编译的文件,并且在HDFS中删除结果输出目录。

如果频繁进行调试,那重复删除便会花费很多的时间,所以可以把这部分内容放置到脚本中去,节省时间。

代码语言:javascript复制
#!/bin/bash

rm -rf SumDeptSalary.*

hadoop fs -rm -r /tmp/mr/data/sum_output

touch SumDeptSalary.java

除此之外,java程序的编译和提交也是重复工作,在测试过程中也可以加到脚本中。

代码语言:javascript复制
#!/bin/bash

export HADOOP_CLASSPATH=${JAVA_HOME}/lib/tools.jar
hadoop com.sun.tools.javac.Main SumDeptSalary.java
jar cf SumDeptSalary.jar SumDeptSalary*.class
hadoop jar SumDeptSalary.jar SumDeptSalary /tmp/mr/data/dept_input/dept /tmp/mr/data/emp_input/emp /tmp/mr/data/sum_output

这些脚本是减少重复执行的时间,为了方便,所以不必写的那么通用,每次测试时重写一个就可以了。

日志查看

再有就是,MapReduce程序在集群中进行调试时,可以在程序中添加System.out来输出信息,当然更推荐使用log4j日志打印。

其中System.out输出的信息,会存放到 $HADOOP_HOME/logs/userlogs目录下对应application的中不同container输出的stderr和stdout文件中。

而log4j日志会存放到syslog中。

因为hadoop依赖中已经添加了log4j的日志包,所以在程序中直接使用即可。

代码语言:javascript复制
// 定义成员变量logger,这里定义到了Mapper类MapClass中
public Logger logger = Logger.getLogger(MapClass.class.getName());
// 在函数中直接调用logger进行日志打印
logger.info("Log4j:进入SetUp方法");

其中log4j的配置文件存放在$HADOOP_HOME/etc/hadoop目录下,可以自定义修改。

程序输出日志后,然而寻找这些日志信息,首先需要在web监控界面查看任务的appication id和任务被提交到了哪些NodeManager中执行,然后分别进入到对应NodeManager节点中查看这些日志,而且因为每次执行的application id不同,导致找到并进入准确的目录花费的时间较长。所以可以编写一个日志查看脚本,从所有节点查询application id对应的日志并返回。

观察application id,末尾的序号是顺序递增的;在虚拟机测试环境中,不同于生产环境的严谨,只需要关注末尾的序号即可,比如0001、0002。所以在脚本中传入的KaTeX parse error: Expected group after '_' at position 28: …配application_*_̲{1}即可。

提供以下脚本,遍历所有从节点,并输出syslog日志。

代码语言:javascript复制
#!/bin/bash

if [ $# -le 0 ]
then
    echo 缺少参数
    exit 1
fi

for n in `cat $HADOOP_HOME/etc/hadoop/slaves`

do
    echo ===========查看节点 $n============
    ssh $n "cat $HADOOP_HOME/logs/userlogs/application_*_${1}/container_*/syslog"
done

使用时,加上grep命令过滤,效果更佳。

0 人点赞