谈谈hadoop日志限制的问题

本文讨论了Hadoop中MapReduce任务的日志限制问题,重点在于mapred.userlog.limit.kb配置如何影响不同类型的MR任务(JavaMR、Streaming、Pipes)。文章分析了syslog、streaming和pipes的日志处理机制,并提到了阿里巴巴版本的特殊限制。建议不要设置过大的日志限制以防止内存溢出,并警告过多的日志输出可能导致磁盘空间耗尽,进而使TaskTracker失效。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、概述

hadoop中主要有三类的MR任务:普通javaMR、streaming、pipes。其中streaming与pipes本质是差不多的,都会创建一个新的进程(除child外的),streaming是基于in、out、err标准输入输出来传递数据的,pipes则是通过socket来传递数据的。要查询他们的具体内容,请google去吧。本文主要讲述他们的日志限制问题。由于他们都是用户自定义的程序,所以往往认为是不可靠的,特别是对磁盘空间的利用,最严重的表现就是写入大量的日志直接把磁盘打满,这样TaskTracker就相当于罢工了。

二、分析

在配置文件中有一个配置项mapred.userlog.limit.kb,默认是0,就是限制用户的日志大小的作用,当配置为10kb的时候,那么任务当写到10k左右的日志的时候就会不再写入日志了。这个参数在三类任务中还是有点差别的。先说出他们之间的关系:

类型\日志stdoutstderrsyslog
普通javaMR官方无限制,阿里巴巴用mapred.systemlog.limit.kb限制超出后任务报错官方无限制,阿里巴巴用mapred.systemlog.limit.kb限制超出后任务报错用官方mapred.userlog.limit.kb,且是在任务结束时打印日志,日志内容为tail -f len部分。len是mapred.userlog.limit.kb*1024/100取整。超出后不报错。
streaming无日志官方无限制,阿里巴巴用mapred.systemlog.limit.kb,任务完成后打印日志,内容不超过mapred.systemlog.limit.kb,内容是head -c  mapred.systemlog.limit.kb*1024,超出后不报错。用官方mapred.userlog.limit.kb,且是在任务结束时打印日志,日志内容为tail -f len部分。len是mapred.userlog.limit.kb*1024/100取整。超出后不报错。
pipes用官方mapred.userlog.limit.kb,任务完成后打印日志,内容不超过mapred.userlog.limit.kb,内容就是 tail -c mapred.userlog.limit.kb*1024,超出后不报错。用官方mapred.userlog.limit.kb,任务完成后打印日志,内容不超过mapred.userlog.limit.kb,内容就是 tail -c mapred.userlog.limit.kb*1024,超出后不报错。用官方mapred.userlog.limit.kb,且是在任务结束时打印日志,日志内容为tail -f len部分。len是mapred.userlog.limit.kb*1024/100取整。超出后不报错。


看起来还是比较乱的,还是简单讲下各自的原理吧。我们可以看出,先抛开阿里巴巴自定义的方式不讲,官方是用mapred.userlog.limit.kb来限制日志的大小的。

主要有三大块:

syslog的所有情况:我们可以看出syslog日志,说白了就是log4j的日志,hadoop定义了一个TaskLogAppender,在task中就是用TaskLogAppender来做手脚的。代码路径:http://svn.apache.org/repos/asf/hadoop/common/tags/release-0.19.1/src/mapred/org/apache/hadoop/mapred/TaskLogAppender.java,他就定义了一个队列Queue<LoggingEvent>,当新产生一个LoggingEvent就放到Queue中,等child主进程运行到finally时调用LogManager.shutdown(),TaskLogAppender close的时候一次性写到磁盘。

streaming的stderr情况:命令是直接用jdk的Process来启动的,启动后把in,out,err的流关联到对象OutputStream及InputStream中,后用MROutputThread线程处理out流,用MRErrorThread线程处理err流。

具体的过程:MROutputThread中OutputCollector.collect会收集out的结果,而MRErrorThread中,结果直接被System.err.println输出。代码在:http://svn.apache.org/repos/asf/hadoop/common/tags/release-0.19.1/src/contrib/streaming/src/java/org/apache/hadoop/streaming/PipeMapRed.java中。

pipes的stdout及stderr情况:如果不熟悉例子就请访问http://wiki.apache.org/hadoop/C++WordCount。其实是用了Application封装Process,这个不同于streaming的情况。大致的启动命令为:

Bash -C ('/Tmp/Hadoop-Dragon.Caol/Mapred/Local/Tasktracker/Archive/-5349814786282004457/h1/examples/bin/wordcount-simple'  < /dev/null  | tail -c 102400 >> /home/dragon.caol/hadoop-0.19.1-dc/bin/../logs/userlogs/job_201210241401_0001/attempt_201210241401_0001_m_000000_0/stdout ; exit $PIPESTATUS ) 2>&1 | tail -c 102400 >> /home/dragon.caol/hadoop-0.19.1-dc/bin/../logs/userlogs/job_201210241401_0001/attempt_201210241401_0001_m_000000_0/stderr ; exit $PIPESTATUS
这个命令还是比较复杂的,大致的意思就是执行 wordcount-simple,把标准正确输出到stdout文件,把标准错误输出到stderr文件。我们看到在命令中有tail -c 102400的字样,说明并不是全部打印。

阿里巴巴版本做的一个限制:这个是在system.out/err打印日志时起作用的,具体的做法就是对out/err重定向,再数数,如果超过mapred.systemlog.limit.kb*1024,则直接抛异常。所以就会使child直接挂掉。但是在streaming中由于是用MRErrorThread线程做这件事情,也没有做特别干涉main线程,所以不会对main线程有影响。

三、总结

1、我们并不建议把mapred.userlog.limit.kb设置较大,如果较大可能会引起内存溢出。

2、阿里巴巴在改造的过程中直接抛出异常,这个也是我们不建议用户打印较多的日志。

3、我们经常发现一些程序,如:perl会打印一些调试的信息,如果不做限制,这些信息最终会把磁盘打满。由于调度器会重新调度,这种错误可能会引起较多的tasktracker罢工。

四、声明

文章可能会重新编辑,如果想浏览最新内容请访问原创博客:http://blog.youkuaiyun.com/bxyz1203/article/details/8107125。由于作者个人知识面有限,如果描述有错误或者遗留之处敬请谅解,再欢迎指出,我们共同进步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值