hive job oom

概括

先概括下,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。

3.reduce内存不足

 错误信息如下:Container [pid=26845,containerID=container_1419056923480_0212_02_000001] is running beyond virtual memory limits. Current usage: 262.8 MB of 2 GB physical memory used; 4.8 GB of 4.2 GB virtual memory used. Killing container.

解决办法:

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

2. 在hive-site.xml中设置,或者在hive shell里调大参数

set mapreduce.map.memory.mb=1024;
set mapreduce.map.java.opts=-Xmx819m;
set mapreduce.reduce.memory.mb=2048;
set mapreduce.reduce.java.opts=-Xmx1638m;

mapreduce.map.memory.mb是向RM申请的内存资源大小

mapreduce.reduce.java.opts 一般只用于配置JVM参数

JVM大小一般是所申请内存的0.75

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)

原因是因为扫描的表的分区太多,上到3千到6千个分区,这样在对计划进行序列化时,仅仅是路径对象Path就会耗去大半Driver,如果Driver设置的heap太小,甚至都会OOM。

解决思路:

1.  减少分区数量,将历史数据做成一张整合表,做成增量数据表,这样分区就很少了。

2. 调大Hive CLI Driver的heap size, 默认是256MB,调节成512MB或者更大。

具体做法是在bin/hive bin/hive-config里可以找到启动CLI的JVM OPTIONS。

这里我们设置

export HADOOP_HEAPSIZE=512

猜你喜欢

转载自my.oschina.net/u/2000675/blog/1810971
OOM
job
今日推荐