Hadoop作业JVM堆大小设置优化

https://www.iteblog.com/archives/981

Container is running beyond memory limitshttp://stackoverflow.com/questions/21005643/container-is-running-beyond-memory-limits`  

[hadoop] - Container [xxxx] is running beyond physical/virtual memory limits. http://www.cnblogs.com/liuming1992/p/5040262.html

当运行mapreduce的时候,有时候会出现异常信息,提示物理内存或者虚拟内存超出限制,默认情况下:虚拟内存是物理内存的2.1倍。异常信息类似如下:

Container [pid=13026,containerID=container_1449820132317_0013_01_000012] is running beyond physical memory limits. Current usage: 1.0 GB of 1 GB physical memory used; 1.7 GB of 2.1 GB virtual memory used. Killing container. Dump of the process-tree for container_1449820132317_0013_01_000012 : |- PID PPID PGRPID SESSID CMD_NAME USER_MODE_TIME(MILLIS) SYSTEM_TIME(MILLIS) VMEM_USAGE(BYTES) RSSMEM_USAGE(PAGES) FULL_CMD_LINE |- 13044 13026 13026 13026 (java) 4479 494 1696595968 271631 /home/hadoop/cdh5.2.4/jdk1.7.0_79/bin/java -Djava.net.preferIPv4Stack=true -xxx

我们可以看到该异常信息是提示物理内存超过限制,但是通过我们查看代码我们发现我们最终使用的内存没有达到1G,只有500M-。(具体原因没有细查)最终我们发现影响这个代码执行的参数分别是:

参数 默认值 描述
yarn.scheduler.minimum-allocation-mb 1024 每个container请求的最低jvm配置,单位m。如果请求的内存小于该值,那么会重新设置为该值。
yarn.scheduler.maximum-allocation-mb 8192 每个container请求的最高jvm配置,单位m。如果大于该值,会被重新设置。
yarn.nodemanager.resource.memory-mb 8192 每个nodemanager节点准备最高内存配置,单位m
yarn.nodemanager.vmem-pmem-ratio 2.1 虚拟内存和物理内存之间的比率,如果提示virtual memory limits的时候,可以将该值调大。
yarn.nodemanager.pmem-check-enabled true 是否进行物理内存限制比较,设置为false,不会进行大小的比较
yarn.nodemanager.vmem-check-enabled false 是否进行虚拟内存限制比较。
mapreduce.map.memory.mb 1024 map内存申请大小,单位m
mapreduce.reduce.memory.mb 1024 reduce内存申请大小,单位m
mapred.child.java.opts -Xmx200 map/reduce执行参数设置,可以参数Hadoop Mapreduce Error: GC overhead limit exceeded

针对该异常信息,有多种方式进行解决:

第一种:

  直接将yarn.nodemanager.pmem-check-enabled和yarn.nodemanager.vmem-check-enabled设置为false,那么可以杜绝异常信息的产生。

第二种:

  如果异常信息提示的是virtual memory不够,那么可以将yarn.nodemanager.vmem-pmem-ratio参数改大,那么也可以避免异常信息的产生。

第三种:

  修改mapreduce参数,设置修改如下:

  mapreduce.map.memory.mb = (1~2倍) * yarn.scheduler.minimum-allocation-mb

  mapreduce.reduce.memory.mb = (1~4倍) * yarn.scheduler.minimum-allocation-mb

  1. mapred.child.java.opts = -XmxTm(T数字要小于map和reduce的设置value)

  2. mapreduce.map.java.opts=-Xmx(<mapreduce.map.memory.mb)m

      mapreduce.reduce.java.opts=-Xmx(<mapreduce.reduce.memory.mb)m

  总结:最终运行参数给定的jvm堆大小必须小于参数指定的map和reduce的memory大小,最好为70%以下。

hadoop源码涉及到地方:

1. org.apache.hadoop.mapred.MapReduceChildJVM.getChildJavaOpts

2. org.apache.hadoop.yarn.server.nodemanager.containermanager.monitor.ContainersMonitorImpl.MonitoringThread.run()<398-465行>(进行内存限制判断)

3. org.apache.hadoop.yarn.server.nodemanager.containermanager.container.ContainerImpl.LaunchTransition.transition()<647-658行>(进行物理内存和虚拟内存大小限制计算和赋值)

  物理内存大小其实就是mapreduce.map.memory.mb和mapreduce.reduce.memory.mb的一个大小值

 

 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

mapred.child.java.opts:当需要处理超大数据(mapper大于10?)最好将值设置成-Xmx1024m或者更高(-Xmx2048m)才能避免出现“核心已转储”这种jvm内存溢出的错误!!

 

http://slaytanic.blog.51cto.com/2057708/1101360/

 

name value Description
hadoop.job.history.location   job历史文件保存路径,无可配置参数,也不用写在配置文件里,默认在logs的history文件夹下。
hadoop.job.history.user.location   用户历史文件存放位置
io.sort.factor 30 这里处理流合并时的文件排序数,我理解为排序时打开的文件数
io.sort.mb 600 排序所使用的内存数量,单位兆,默认1,我记得是不能超过mapred.child.java.opt设置,否则会OOM
mapred.job.tracker hadoopmaster:9001 连接jobtrack服务器的配置项,默认不写是local,map数1,reduce数1
mapred.job.tracker.http.address 0.0.0.0:50030 jobtracker的tracker页面服务监听地址
mapred.job.tracker.handler.count 15 jobtracker服务的线程数
mapred.task.tracker.report.address 127.0.0.1:0 tasktracker监听的服务器,无需配置,且官方不建议自行修改
mapred.local.dir /data1/hdfs/mapred/local,
/data2/hdfs/mapred/local,
...
mapred做本地计算所使用的文件夹,可以配置多块硬盘,逗号分隔
mapred.system.dir /data1/hdfs/mapred/system,
/data2/hdfs/mapred/system,
...
mapred存放控制文件所使用的文件夹,可配置多块硬盘,逗号分隔。
mapred.temp.dir /data1/hdfs/mapred/temp,
/data2/hdfs/mapred/temp,
...
mapred共享的临时文件夹路径,解释同上。
mapred.local.dir.minspacestart 1073741824 本地运算文件夹剩余空间低于该值则不在本地做计算。字节配置,默认0
mapred.local.dir.minspacekill 1073741824 本地计算文件夹剩余空间低于该值则不再申请新的任务,字节数,默认0
mapred.tasktracker.expiry.interval 60000 TT在这个时间内没有发送心跳,则认为TT已经挂了。单位毫秒
mapred.map.tasks 2 默认每个job所使用的map数,意思是假设设置dfs块大小为64M,需要排序一个60M的文件,也会开启2个map线程,当jobtracker设置为本地是不起作用。
mapred.reduce.tasks 1 解释同上
mapred.jobtracker.restart.recover true | false 重启时开启任务恢复,默认false
mapred.jobtracker.taskScheduler org.apache.hadoop.mapred.
CapacityTaskScheduler

org.apache.hadoop.mapred.
JobQueueTaskScheduler

org.apache.hadoop.mapred.
FairScheduler
重要的东西,开启任务管理器,不设置的话,hadoop默认是FIFO调度器,其他可以使用公平和计算能力调度器
mapred.reduce.parallel.copies 10 reduce在shuffle阶段使用的并行复制数,默认5
mapred.child.java.opts

-Xmx2048m

-Djava.library.path=
/opt/hadoopgpl/native/
Linux-amd64-64

每个TT子进程所使用的虚拟机内存大小
tasktracker.http.threads 50 TT用来跟踪task任务的http server的线程数
mapred.task.tracker.http.address 0.0.0.0:50060 TT默认监听的httpIP和端口,默认可以不写。端口写0则随机使用。
mapred.output.compress true | false 任务结果采用压缩输出,默认false,建议false
mapred.output.compression.codec org.apache.hadoop.io.
compress.DefaultCodec
输出结果所使用的编解码器,也可以用gz或者bzip2或者lzo或者snappy等
mapred.compress.map.output true | false map输出结果在进行网络交换前是否以压缩格式输出,默认false,建议true,可以减小带宽占用,代价是会慢一些。
mapred.map.output.compression.codec com.hadoop.compression.
lzo.LzoCodec
map阶段压缩输出所使用的编解码器
map.sort.class org.apache.hadoop.util.
QuickSort
map输出排序所使用的算法,默认快排。
mapred.hosts conf/mhost.allow 允许连接JT的TT服务器列表,空值全部允许
mapred.hosts.exclude conf/mhost.deny 禁止连接JT的TT列表,节点摘除是很有作用。
mapred.queue.names ETL,rush,default 配合调度器使用的队列名列表,逗号分隔
mapred.tasktracker.map.
tasks.maximum
12 每服务器允许启动的最大map槽位数。
mapred.tasktracker.reduce.
tasks.maximum
6 每服务器允许启动的最大reduce槽位数

 

http://blog.csdn.net/lalaguozhe/article/details/9076895

​前一阵子发现用户提交的Hive query和Hadoop job会导致集群的load非常高,经查看配置,发现很多用户擅自将mapred.child.Java.opts设置的非常大,比如-Xmx4096m(我们默认设置是-Xmx1024m),  导致了tasktracker上内存资源耗尽,进而开始不断swap磁盘上数据,load飙升

TaskTracker在spawn一个map/reduce task jvm的时候,会根据用户JobConf里面的值设定jvm的参数,然后写入一个taskjvm.sh文件中,然后调用Linux命令"bin/bash -c taskjvm.sh"来执行task,

mapred.child.java.opts就是设定jvm的参数之一,在新版本中已经标注Deprecateded,取而代之的是区分Map task和Reduce task的jvm opts,mapred.map.child.java.opts和mapred.reduce.child.java.opts(默认值为-Xmx200m)

当用户在不设该值情况下,会以最大1G jvm heap size启动task,有可能导致OutOfMemory,所以最简单的做法就是设大参数,并且由于这个值不是final,所以用户在自己的mapred-site.xml中可以覆盖默认值。但是如果很多用户都无限度设置的话,high load问题就来了。

 

其实在构造JVM Args的过程中,是有另外一个admin参数可以覆盖用户端设置的mapreduce.admin.map.child.java.opts, mapreduce.admin.reduce.child.java.opts

经测试,如果相同的jvm arg如果写在后面,比如"-Xmx4000m -Xmx1000m",后面的会覆盖前面的,“-Xmx1000m”会最终生效,通过这种方式,我们就可以有限度的控制heap size了

 

终在mapred-site.xml中加上

 

<property>
      <name>mapreduce.admin.map.child.java.opts</name>
      <value>-Xmx1024m</value>
</property>
<property>
      <name>mapreduce.admin.reduce.child.java.opts</name>
      <value>-Xmx1536m</value>
</property>
posted @ 2016-11-07 13:04  wangq17  阅读(12948)  评论(0编辑  收藏  举报