hive丢数据了,怎么办

说明:这个问题是之前在上家,hive版本是hive-1.1.0,集群规模不大,当时只有500多台

一个周五将要下班的时候接到同事的电话说一个作业丢数据了将近200万,顿时隐隐感觉不妙,立马投入查看作业日志的进程中。分析作业日志发现临时表的结果输出是正确的,插入目标表的行数是不正确(下面有图说明),当时推断以为是插入目标表出现的错误,然后就分析插入目标的mapreduce日志,通过计算还真发现少读了一个文件,但是这个mapreduce日志又没有任何错误和警告,都是成功的,头大了。这台调度作业的机器是新机器,还以为是这个原因导致的,分析发现和新机器无关。同时把作业放到机器上重新跑生成临时表,看看结果是否正确。一跑两个小时,等到结果出来了,一看数据也丢失了,大喜!能复现,这就好办了,容易查找问题了。

生成临时表的输出的统计信息(这个数据是正确的)

生成目标表输出的统计信息(这个数据是错误的)

分析这个最后创建目标表的mapreduce日志,同时在进行跑其他类型的测试。测试类型有:1、创建临时表用textfile存储,因为线上都是orc格式存储;2、减少那天刚上线的字段,刚好在执行作业前同事上线了50多个字段(当时就怀疑这个字段太多造成的,因为以前遇到过一个作业union all太多造成后面增加的union all的数据丢失(解决方案union all拆分,这个也是hive的bug,没去代码层面解决)。说一下这个表的背景:这是一个大宽表,有1000多个字段,都是在做left join,这个字段不停的增加),3、跑这个作业后一天的数据。在测试这个作业时同事发现创建临时表的task中有warn信息。测试上面三种结果发现第1、2种结果正确,第3种结果不正确是少数据,这就确定了和orc存储格式有关也和增加字段有关。把第1种textfile格式的生成的数据插入到orc格式的表中,发现结果也不会出现错误。

task中的warn信息

找warn信息的输出代码,在OrcFileMergeOperator类中checkCompatibility方法。输出告警是以下代码,那么这个和compressBuffSize有关了

调用输出这个warn信息之前有以下代码,然后跟踪以下代码

这里才是去做真正orc合并。里面有个bufferSizeValue,这个参数bufferSizeValue = HiveConf.getIntVar(conf, HIVE_ORC_DEFAULT_BUFFER_SIZE);在WriterImpl类中这个值会根据计算去得到估计buffer大小

进入这个方法,发现列的总数大于列线程总数才会去重新计算这个估算值,这个值为1000,刚好满足我们这个列的情况

分析到这里,我们发现就是尽量别让他估算值生效,也就是bufferSize尽量减小,那么estBufferSize就会返回bufferSize。最后我们生产上修改hive.exec.orc.default.buffer.size=8192,最终跑出来的结果正确。这个过程还可以继续好好分析。

问题解决了,也快凌晨12点了。主要是作业运行时间太久,每次运行一次需要2小时。

后来经过查看hive的patch,发现这个patch修复了以上问题HIVE-11807

举报
评论 0