牛骨文教育服务平台(让学习变的简单)
博文笔记

Hive中跑MapReduce Job出现OOM问题分析及解决

创建时间:2014-11-21 投稿人: 浏览次数:203

一、引子

今天在跑一段很复杂而且涉及数据量10多年的N个表join的长SQL时,发生了OOM的异常。


由于一个map通常配置只有64MB或者128MB,则在Map阶段出现OOM的情况很少见。所以一般发生在reduce阶段。

但是今天这个异常详细的看后,会发现既不是map阶段,也不是reduce阶段,发现不是执行过程,而是driver提交job阶段就OOM了。
Hive中XMLEncoder序列化MapredWork引发OutOfMemoryError

XMLEncoder导致java.lang.OutOfMemoryError: GC overhead limit exceeded


二、概括回顾

先概括下,Hive中出现OOM的异常原因大致分为以下几种:

1. Map阶段OOM。
2. Reduce阶段OOM。
3. Driver提交Job阶段OOM。


Map阶段OOM:

1. 发生OOM的几率很小,除非你程序的逻辑不正常,亦或是程序写的不高效,产生垃圾太多。
 

Reduce阶段OOM:

1. data skew 数据倾斜

data skew是引发这个的一个原因。 
key分布不均匀,导致某一个reduce所处理的数据超过预期,导致jvm频繁GC。

2. value对象过多或者过大

某个reduce中的value堆积的对象过多,导致jvm频繁GC。


解决办法:

1. 增加reduce个数,set mapred.reduce.tasks=300,。

2. 在hive-site.xml中设置,或者在hive shell里设置 set  mapred.child.java.opts = -Xmx512m

   或者只设置reduce的最大heap为2G,并设置垃圾回收器的类型为并行标记回收器,这样可以显著减少GC停顿,但是稍微耗费CPU。

   set mapred.reduce.child.java.opts=-Xmx2g -XX:+UseConcMarkSweepGC;

3. 使用map join 代替 common join. 可以set hive.auto.convert.join = true

4. 设置 hive.optimize.skewjoin = true 来解决数据倾斜问题


Driver提交job阶段OOM:

 job产生的执行计划的条目太多,比如扫描的分区过多,上到4k-6k个分区的时候,并且是好几张表的分区都很多时,这时做join。

究其原因,是 因为序列化时,会将这些分区,即hdfs文件路径,封装为Path对象,这样,如果对象太多了,而且Driver启动的时候设置的heap size太小,则会导致在Driver内序列化这些MapRedWork时,生成的对象太多,导致频繁GC,则会引发如下异常:

java.lang.OutOfMemoryError: GC overhead limit exceeded
at sun.nio.cs.UTF_8.newEncoder(UTF_8.java:53)
at java.beans.XMLEncoder.createString(XMLEncoder.java:572)


三、诊断问题

如何诊断到了问题:

在网上搜异常,在Hive的IRA发现一个issues,和我的情况类似:
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。