hive程序报错OOM,内存不足,OutOfMemoryError: Java heap space等解决方式

执行hive定时任务,发现有个定时任务报如下错误,Error: Java heap space.hive程序报错OOM,内存不足,OutOfMemoryError: Java heap space等解决方式_第1张图片

     查看hadoop日志发现,实际上有4个map没有执行成功,而reduce就没有执行,说明调度平台显示的日志信息不准确。进入对应的4个map中查看日志,发现真实报内存溢出错误hive程序报错OOM,内存不足,OutOfMemoryError: Java heap space等解决方式_第2张图片

        原来是有4个map出现内存溢出问题,上图查看实际使用值为1575879256≈1.47g,执行失败。这种情况我们分析,有可能是map的切片设置的太大,而系统给每个map可以分配的最大内存设置的太小,所有造成内存溢出。
        通过set mapreduce.map.memory.mb;查看可知

         set mapreduce.map.memory.mb=2048.所以每个map可以使用的内存完全够用。

       通过hive中查询,原来系统给堆内存设置的大小是1536Mb,即1.5G,而实际中执行切片设置的过大,造成计算该切片所需要的堆内存为1.47g,尽快比1.5g小,但是jvm本身就需要运行就需要内存以及其他消耗,造成堆内存溢出。

hive> set mapred.child.java.opts;
mapred.child.java.opts=-Xmx1536m -Xms1536m -Xmn256m -XX:SurvivorRatio=6 -XX:MaxPermSize=128m -XX:+PrintGCDetails 
-XX:+PrintGCTimeStamps -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=80  -XX:GCTimeLimit=90 
-XX:GCHeapFreeLimit=10 -XX:ParallelGCThreads=8

        解决方式:1.将系统设置的set mapred.max.split.size = 300000000;我们原先的最大分片设置成200000000.降低切片大小,这样的坏处是会产生更多的map去执行。

       2.将上面集群的heap.size设置的更大些,比如2048(2g).设置方式如下:  

1.写到配置文件里,比如设置成2G
     
        mapred.child.java.opts
        -Xmx2048m 
     
2.当然也可以直接配置,直接在查询出来的值中修改
任务启动的jvm参数,默认值-Xmx200m,建议值-XX:-UseGCOverheadLimit -Xms512m -Xmx2048m -verbose:gc -Xloggc:/tmp/@[email protected]
可以直接修改

        当然以上的配置信息,最好都直接写到每个hive定时任务里面即可,不用配置到集群里固定信息,这样能更好地利用集群资源。

尖叫提示:

1.报内存不足发生的阶段:

  1. Map阶段
  2. Shuffle阶段
  3. Reduce阶段

2.oom解决方式

2.1  内存不足发生map阶段

       一般存在MapJoin才会出现这种OOM。通过设置参数set hive.auto.convert.join = false转成reduce端的Common Join。其次如果是common join报oom一般就是切片太大了,尤其注意hdfs显示的大小是压缩后大小,如果切片设置的太大,解压后处理很容易撑爆内存。这个时候通过如下参数调小map输入量

set mapred.max.split.size=256000000  
set mapred.min.split.size=10000000
set mapred.min.split.size.per.node=8000000 --每个节点处理的最小split
set mapred.min.split.size.per.rack=8000000 --每个机架处理的最小slit.

2.2 内存不足发生shuffle阶段

    这种一般是因为由于map的输出较大,但shuffle阶段选择的是拷贝map输出到内存导致。降低单个shuffle能够消耗的内存占reduce所有内存的比例(set mapreduce.reduce.shuffle.memory.limit.percent=0.10),使得shuffle阶段拷贝map输出时选择落

3.3 内存不足发生在reduce阶段

单个reduce处理数据量过大,通过设置参数mapred.reduce.tasks mapreduce.job.reduces 修改reduce个数,或者通过

set hive.exec.reducers.bytes.per.reducer=300000000  --减小每个reduce聚合的数据量

来以进一步分散压力。但如果存在数据倾斜的情况,单纯修改reduce个数没有用,需要对应的处理,具体参考我的其他博客。

你可能感兴趣的:(Hive编程和数据仓库)