设为首页 收藏本站
查看: 1411|回复: 4

[经验分享] Hadoop运维记录系列(六)

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2013-10-30 09:01:33 | 显示全部楼层 |阅读模式
这两天有业务部门反馈,总有hive跑某天的log失败。看了一下log,虽然各种报错不一样,但基本都是OOM,追了一下午,终于追出来原因了,特此记录一下。




这个问题很诡异,map阶段oom,按说map的时候一个map对应一个数据块,最大也就占用128M内存,怎么会溢出呢,通常都应该是reduce溢出才对。先看看各个hadoop节点的tasktracker报的错误log。

节点一


2013-05-08 20:59:06,467 FATAL org.apache.hadoop.mapred.Child: Error running child : java.lang.OutOfMemoryError: Java heap space

at java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:39)

at java.nio.ByteBuffer.allocate(ByteBuffer.java:312)

at sun.nio.cs.StreamDecoder.<init>(StreamDecoder.java:231)

at sun.nio.cs.StreamDecoder.<init>(StreamDecoder.java:211)

at sun.nio.cs.StreamDecoder.forInputStreamReader(StreamDecoder.java:50)

at java.io.InputStreamReader.<init>(InputStreamReader.java:57)

at org.apache.hadoop.util.Shell.runCommand(Shell.java:211)

at org.apache.hadoop.util.Shell.run(Shell.java:182)

at org.apache.hadoop.util.Shell$ShellCommandExecutor.execute(Shell.java:375)

at org.apache.hadoop.util.Shell.execCommand(Shell.java:461)

at org.apache.hadoop.util.Shell.execCommand(Shell.java:444)

at org.apache.hadoop.fs.FileUtil.execCommand(FileUtil.java:710)

at org.apache.hadoop.fs.RawLocalFileSystem$RawLocalFileStatus.loadPermissionInfo(RawLocalFileSystem.java:443)

at org.apache.hadoop.fs.RawLocalFileSystem$RawLocalFileStatus.getOwner(RawLocalFileSystem.java:426)

at org.apache.hadoop.mapred.TaskLog.obtainLogDirOwner(TaskLog.java:267)

at org.apache.hadoop.mapred.TaskLogsTruncater.truncateLogs(TaskLogsTruncater.java:124)

at org.apache.hadoop.mapred.Child$4.run(Child.java:260)

at java.security.AccessController.doPrivileged(Native Method)

at javax.security.auth.Subject.doAs(Subject.java:396)

at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1121)

at org.apache.hadoop.mapred.Child.main(Child.java:249)




节点二


2013-05-08 20:56:37,012 INFO org.apache.hadoop.mapred.Task: Communication exception: java.lang.OutOfMemoryError: Java heap space

at java.io.BufferedReader.<init>(BufferedReader.java:80)

at java.io.BufferedReader.<init>(BufferedReader.java:91)

at org.apache.hadoop.util.ProcfsBasedProcessTree.constructProcessInfo(ProcfsBasedProcessTree.java:396)

at org.apache.hadoop.util.ProcfsBasedProcessTree.getProcessTree(ProcfsBasedProcessTree.java:151)

at org.apache.hadoop.util.LinuxResourceCalculatorPlugin.getProcResourceValues(LinuxResourceCalculatorPlugin.java:401)

at org.apache.hadoop.mapred.Task.updateResourceCounters(Task.java:808)

at org.apache.hadoop.mapred.Task.updateCounters(Task.java:830)

at org.apache.hadoop.mapred.Task.access$600(Task.java:66)

at org.apache.hadoop.mapred.Task$TaskReporter.run(Task.java:666)

at java.lang.Thread.run(Thread.java:662)




节点三


2013-05-08 21:02:26,489 FATAL org.apache.hadoop.mapred.Child: Error running child : java.lang.OutOfMemoryError: Java heap space

at com.sun.org.apache.xerces.internal.xni.XMLString.toString(XMLString.java:185)

at com.sun.org.apache.xerces.internal.parsers.AbstractDOMParser.characters(AbstractDOMParser.java:1185)

at com.sun.org.apache.xerces.internal.xinclude.XIncludeHandler.characters(XIncludeHandler.java:1085)

at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:464)

at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808)

at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)

at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)

at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:232)

at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:284)

at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:180)

at org.apache.hadoop.conf.Configuration.loadResource(Configuration.java:1168)

at org.apache.hadoop.conf.Configuration.loadResources(Configuration.java:1119)

at org.apache.hadoop.conf.Configuration.getProps(Configuration.java:1063)

at org.apache.hadoop.conf.Configuration.get(Configuration.java:416)

at org.apache.hadoop.conf.Configuration.getLong(Configuration.java:521)

at org.apache.hadoop.io.nativeio.NativeIO.ensureInitialized(NativeIO.java:120)

at org.apache.hadoop.io.nativeio.NativeIO.getOwner(NativeIO.java:103)

at org.apache.hadoop.io.SecureIOUtils.openForRead(SecureIOUtils.java:116)

at org.apache.hadoop.mapred.TaskLog.getAllLogsFileDetails(TaskLog.java:191)

at org.apache.hadoop.mapred.TaskLogsTruncater.getAllLogsFileDetails(TaskLogsTruncater.java:342)

at org.apache.hadoop.mapred.TaskLogsTruncater.truncateLogs(TaskLogsTruncater.java:134)

at org.apache.hadoop.mapred.Child$4.run(Child.java:260)

at java.security.AccessController.doPrivileged(Native Method)

at javax.security.auth.Subject.doAs(Subject.java:396)

at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1121)

at org.apache.hadoop.mapred.Child.main(Child.java:249)




每个节点报错信息还都不一样,这就很让人头疼,不过下面这个log倒是殊途同归,所有节点最后都报了个无关紧要的文件错误。


2013-05-08 20:58:47,568 ERROR org.apache.hadoop.security.UserGroupInformation: PriviledgedActionException as:hadoop cause:org.apache.hadoop.io.SecureIOUtils$AlreadyExistsException: EEXIST: File exists

2013-05-08 20:58:47,569 WARN org.apache.hadoop.mapred.Child: Error running child

org.apache.hadoop.io.SecureIOUtils$AlreadyExistsException: EEXIST: File exists

at org.apache.hadoop.io.SecureIOUtils.createForWrite(SecureIOUtils.java:167)

at org.apache.hadoop.mapred.TaskLog.writeToIndexFile(TaskLog.java:312)

at org.apache.hadoop.mapred.TaskLog.syncLogs(TaskLog.java:385)

at org.apache.hadoop.mapred.Child$4.run(Child.java:257)

at java.security.AccessController.doPrivileged(Native Method)

at javax.security.auth.Subject.doAs(Subject.java:396)

at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1121)

at org.apache.hadoop.mapred.Child.main(Child.java:249)

Caused by: EEXIST: File exists

at org.apache.hadoop.io.nativeio.NativeIO.open(Native Method)

at org.apache.hadoop.io.SecureIOUtils.createForWrite(SecureIOUtils.java:161)

... 7 more




最后这个log的确是殊途同归的,因为每个map在OOM之后,tasktracker会尝试重新启动map并重新创建相同的TaskLog的文件句柄,但因为是异常终止的,之前的TaskLog的文件句柄已经被创建,但是OOM了,这个句柄没有正常关闭,所以会报写失败的异常。源码如下





/**

* Open the specified File for write access, ensuring that it does not exist.

* @param f the file that we want to create

* @param permissions we want to have on the file (if security is enabled)

*

* @throws AlreadyExistsException if the file already exists

* @throws IOException if any other error occurred

*/

public static FileOutputStream createForWrite(File f, int permissions)

throws IOException {

  if (skipSecurity) {

    return insecureCreateForWrite(f, permissions);

  } else {

    // Use the native wrapper around open(2)

    try {

      FileDescriptor fd = NativeIO.open(f.getAbsolutePath(),

        NativeIO.O_WRONLY | NativeIO.O_CREAT | NativeIO.O_EXCL,

        permissions);

      return new FileOutputStream(fd);

    } catch (NativeIOException nioe) {

      if (nioe.getErrno() == Errno.EEXIST) {

        throw new AlreadyExistsException(nioe);

      }

      throw nioe;

    }

  }

}












De这个bug有点难度,按说map阶段是不容易溢出的,map阶段溢出最有可能发生的应该是在sort和spill阶段,也就是io.sort.mb参数所控制的环形内存所做的快速排序上,但是这个内存已经设置为600M足够大了,mapred.map.child.java.opts也设置了1.5G,也够了。然后由于每个节点的溢出错误都不一样,但是主要有一个共同点,是节点一、二heap和buffer读写问题。




回去再看他的HiveQL,很简单,做了一个uid的count distinct,然后做了几个字段的group by就没了。看来问题可能主要还是出在这个uid上面,他这个hql是特定选的4月某一天。然后尝试选3月的某天,没问题,选5月的某天也没问题,5月日志肯定比4月要大。这样就排除掉了日志大小的问题,一天才100G日志而已,比这个大的有的是。肯定不是因为日志太大引发的map阶段oom。




继续排除,然后高潮来了,选这一天的前一天,也没问题,选后一天,也没问题。看来问题就出在这一天的日志上面了。选了一下distinct length(uid),发现有一条uid有71个字节,正常的应该都是32字节。然后剔除uid长度为71的uid,也就是加上where length(uid) != 71做跟报错HQL相同的group by立马正常了,然后尝试原报错HQL,仍然报错,看来就是他了。




单独写个select * from xxx where length(uid) = 71的HQL抽出这条uid,发现里面含有特殊字符,就是这条uid捣的鬼了。可能是nginx在日志接收过程中发生了TCP错误,然后数据清洗没有洗掉。由于含有特殊字符,Hadoop在做本地map的时候,数据流含有可能是EOF或者NOP之类的东西,导致无法用BufferedReader读取和用StreamDecoder解释,跟做本地任务执行时继承到map.local.dir里的job.xml指定的InputFormat对不上,说白了也就是无法正常执行,然后就溢出了。




这个问题太操蛋了,但是也可能很常见,日志清洗总不能100%保证正确。就一行特殊字符的log,坑了我一下午。这个日志一天一百多G,总不能拿肉眼看,awk跑正则更没戏,总得想点变通的办法。Hive出的问题,最后还是用Hive把问题揪出来了。搞hadoop集群运维不能光搞hadoop的运行进程稳定,还得了解hadoop原理,还得了解业务。还好接手集群运维之前我是写map/reduce的,还算有一点点编程的基础,了解一些业务,比较容易分析一些bug。但是还是不得不吐槽,特殊字符真是个大坑。回头得要求他们把清洗程序加点过滤条件。




上亿行里面就一行bad log,典型的一颗老鼠屎污染了一片海。





运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-10079-1-1.html 上篇帖子: Hadoop运维记录系列(五) 下篇帖子: Hadoop运维记录系列(七) 记录

尚未签到

发表于 2013-11-15 23:18:53 | 显示全部楼层
站的更高,尿的更远。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

尚未签到

发表于 2013-12-3 09:13:37 | 显示全部楼层
没有过不去的坎,只有不走路的人,所以路都是自己走出来的

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

尚未签到

发表于 2013-12-15 16:33:58 | 显示全部楼层
如果我的真诚对你来说是种谎言的话,那我宁愿选择沉默

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

尚未签到

发表于 2013-12-24 17:52:55 | 显示全部楼层
没有过不去的坎,只有不走路的人,所以路都是自己走出来的

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表