新疆XX局点Hive任务内存不足问题分析报告

发布时间:  2016-09-08 浏览次数:  672 下载次数:  0
问题描述

集群版本: FusionInsight V100R002C30SPC605
集群环境: 3+29部署。
问题现象:主要是Hive业务出现Hive开户数据表导入任务失败。

告警信息

告警信息:maptask报错内存不足:2016-08-09 16:33:42,044 FATAL [main] org.apache.hadoop.mapred.YarnChild: Error running child : java.lang.OutOfMemoryError: Java heap space。

处理过程

通过分析失败Hive任务的日志发现,大部分maptask是成功的,由于个别maptask内存不够用导致整个Hive任务一直无法成功。

对比分析成功和失败的maptask日志,可以看到:

1.每个maptask都是出来256MB的数据量

2.maptask处理的数据来源于上游一个生成数据的python程序,数据为文本格式

数据存放在hdfs的以下路径

/hzsrc/external/khzl_xj_yd/3aca1f56-d7d0-37c4-b37b-f2a3340182a7

3.成功的maptask处理的数据条数基本都在30万条记录左右

例如:

2016-08-09 16:34:26,508 INFO [main] org.apache.hadoop.hive.ql.exec.mr.ExecMapper: ExecMapper: processed 291360 rows: used memory = 875235352

2016-08-09 16:34:42,920 INFO [main] org.apache.hadoop.hive.ql.exec.mr.ExecMapper: ExecMapper: processed 333332 rows: used memory = 952543688

4.失败的maptask处理的数据条数少一个数量级,都在2万条左右

例如:

2016-08-09 16:33:42,036 INFO [main] org.apache.hadoop.hive.ql.exec.mr.ExecMapper: ExecMapper: processed 21520 rows: used memory = 1692241928

5.失败的maptask报错信息如下

2016-08-09 16:33:42,044 FATAL [main] org.apache.hadoop.mapred.YarnChild: Error running child : java.lang.OutOfMemoryError: Java heap space

        at java.nio.HeapCharBuffer.<init>(HeapCharBuffer.java:57)

        at java.nio.CharBuffer.allocate(CharBuffer.java:331)

        at java.nio.charset.CharsetDecoder.decode(CharsetDecoder.java:792)

        at org.apache.hadoop.io.Text.decode(Text.java:416)

        at org.apache.hadoop.io.Text.decode(Text.java:393)

        at org.apache.hadoop.io.Text.toString(Text.java:280)

        at org.apache.hadoop.hive.serde2.lazy.objectinspector.primitive.LazyStringObjectInspector.getPrimitiveJavaObject(LazyStringObjectInspector.java:56)

        at org.apache.hadoop.hive.ql.io.orc.WriterImpl$StringTreeWriter.getStringValue(WriterImpl.java:935)

        at org.apache.hadoop.hive.ql.io.orc.WriterImpl$StringTreeWriter.write(WriterImpl.java:942)

        at org.apache.hadoop.hive.ql.io.orc.WriterImpl$StructTreeWriter.write(WriterImpl.java:1391)

        at org.apache.hadoop.hive.ql.io.orc.WriterImpl.addRow(WriterImpl.java:2019)

        at org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat$OrcRecordWriter.write(OrcOutputFormat.java:85)

        at org.apache.hadoop.hive.ql.exec.FileSinkOperator.processOp(FileSinkOperator.java:625)

        at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:793)

        at org.apache.hadoop.hive.ql.exec.SelectOperator.processOp(SelectOperator.java:87)

        at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:793)

        at org.apache.hadoop.hive.ql.exec.TableScanOperator.processOp(TableScanOperator.java:92)

        at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:793)

        at org.apache.hadoop.hive.ql.exec.MapOperator.process(MapOperator.java:540)

        at org.apache.hadoop.hive.ql.exec.mr.ExecMapper.map(ExecMapper.java:177)

        at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:54)

        at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:452)

        at org.apache.hadoop.mapred.MapTask.run(MapTask.java:342)

        at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:178)

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

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

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

        at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:173)

该堆栈说明当前maptask已经处理完了从hdfs数据读取记录的阶段,在将读取的数据转化为orc file(目标表客户使用了orc格式)输出时内存不足。
综上所述,当前的问题就在于失败的maptask在读取原始文本数据时没有正确的处理行数,导致误把剩下的20多万条记录当做了一行数据量很大的记录进行处理,最终在转化为orc格式存储时内存不足。

根因

这种问题通常是原始数据文件存在行分隔符处理不正确或者是文本中有某些异常符号,导致文本数据读取异常。由于存在问题的文件已经删除,且最新生成的文件一直都成功导入,不存在上述问题,所以具体当时原始数据文件到底有什么问题无法分析。

解决方案

根据失败的maptask定位到具体有问题的数据文件,将数据文件挪走,重新触发导入任务即可成功。由于Hive入库时,是按行插入数据,挪走该部分数据不会导致入库数据出现数据不一致问题,只需要重新处理该部分数据再进行导入即可。针对保留的存在问题的文件分析该文本数据到底存在什么问题,导致根据客户指定的行分隔符无法正常读取正确行数。
根据失败的maptask定位具体有问题的文件的方式如下:
1.到jobhistory页面进入失败任务的失败的 map task查看日志,或从hdfs上“/tmp/logs/bigdata/logs/application_任务号”路径获取日志。
2.在失败的map task日志中搜索“Processing split”,可以查到如下信息:
2016-08-09 16:33:19,445 INFO [main] org.apache.hadoop.mapred.MapTask: Processing split: Paths:/hzsrc/external/khzl_xj_yd/3aca1f56-d7d0-37c4-b37b-f2a3340182a7/KHZL_XJ_YD@2016070404@append@337d27a0-ce7e-3732-944f-fc2239122b0e.6491959.4880125171.dat:1073741824+134217728,/hzsrc/external/khzl_xj_yd/3aca1f56-d7d0-37c4-b37b-f2a3340182a7/KHZL_XJ_YD@2016070404@append@33f6e047-e5e3-32c0-8407-959282b435b6.7479369.5504391741.dat:402653184+134217728InputFormatClass: org.apache.hadoop.mapred.TextInputFormat
上述日志里就是有问题的源数据文件。


END