赞
踩
执行hive定时任务,发现有个定时任务报如下错误,Error: Java heap space.
查看hadoop日志发现,实际上有4个map没有执行成功,而reduce就没有执行,说明调度平台显示的日志信息不准确。进入对应的4个map中查看日志,发现真实报内存溢出错误
原来是有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
- <property>
- <name >mapred.child.java.opts</name>
- <value>-Xmx2048m </value>
- </property>
- 2.当然也可以直接配置,直接在查询出来的值中修改
- 任务启动的jvm参数,默认值-Xmx200m,建议值-XX:-UseGCOverheadLimit -Xms512m -Xmx2048m -verbose:gc -Xloggc:/tmp/@taskid@.gc
- 可以直接修改
当然以上的配置信息,最好都直接写到每个hive定时任务里面即可,不用配置到集群里固定信息,这样能更好地利用集群资源。
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聚合的数据量
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。