前段时间,公司Hadoop集群整体的负载很高,查了一下原因,发现原来是客户端那边在每一个作业上擅自配置了很大的堆空间,从而导致集群负载很高。下面我就来讲讲怎么来现在客户端那边的JVM堆大小的设置。
我们知道,在mapred-site.xml配置文件里面有个mapred.child.java.opts配置,专门来配置一些诸如堆、垃圾回收之类的。看下下面的配置:

  1. <property>
  2. <name>mapred.child.java.opts</name>
  3. <value>-Xmx200m</value>
  4. <description>Java opts for the task tracker child processes.
  5. The following symbol, if present, will be interpolated: @taskid@ is
  6. replaced by current TaskID. Any other occurrences of '@' will go unchanged.
  7. For example, to enable verbose gc logging to a file named for the taskid in
  8. /tmp and to set the heap maximum to be a gigabyte, pass a 'value' of:-Xmx1024m -verbose:gc -Xloggc:/tmp/@taskid@.gc
  9. The configuration variable mapred.child.ulimit can be used to control the
  10. maximum virtual memory of the child processes.
  11. </description>
  12. </property>

默认情况下,-Xmx都是配置200m的,但是在实际情况下,这个显然是不够用的,所以导致客户端那边会设置更大的值。那怎么来限制用户随便设置Xmx的值呢?有下面两种方法:

  

一、可以自己定义一个变量,比如如下:

  1. <property>
  2. <name>mapred.task.java.opts</name>
  3. <value>-Xmx2000m</value>
  4. </property>
  5.  
  6. <property>
  7. <name>mapred.child.java.opts</name>
  8. <value>${mapred.task.java.opts} -Xmx1000m</value>
  9. <final>true</final>
  10. </property>

  上面的mapred.task.java.opts属性是我们自己定义的,可以公布给用户配置;然后在mapred.child.java.opts中获取到mapred.task.java.opts的值,同时mapred.child.java.opts属性的final被设置为true,也就是不让客户修改。所以用户对mapred.child.java.opts直接配置是无效的;而且这里我们在获取${mapred.task.java.opts}之后再添加了-Xmx1000m,而在Java中,如果相同的jvm arg写在一起,比如”-Xmx2000m -Xmx1000m”,后面的会覆盖前面的,也就是说最终“-Xmx1000m”才会生效,通过这种方式,我们就可以有限度的控制客户端那边的heap size了。同样的道理,其他想覆盖的参数我们也可以写到后面。

我们可以通过

  1. <property>
  2. <name>mapred.map.child.java.opts</name>
  3. <value>
  4. -Xmx512M
  5. </value>
  6. </property>
  7.  
  8. <property>
  9. <name>mapred.reduce.child.java.opts</name>
  10. <value>
  11. -Xmx1024M
  12. </value>
  13. </property>

来分别配置作业的Map和Reduce阶段的heap的大小。

  

二、通过mapreduce.admin.map.child.java.opts和和mapreduce.admin.reduce.child.java.opts设定

  上述限制客户端那边随便设置堆大小是通过重新定义一个变量给用户使用,这样用户得使用新的变量来定义一些JVM相关的设定,如果用户那边的脚本非常多,他们就需要一个一个脚本的修改mapred.child.java.opts为mapred.task.java.opts。这样会恨不方便。这里介绍另外一种方法。可以通过mapreduce.admin.map.child.java.opts和mapreduce.admin.reduce.child.java.opts来限定作业map和reduce的堆的大小。他们都是管理员设定的map/reduce阶段申请的container的默认JVM启动参数。启动container的命令行会先连接管理员设定参数,然后再连接用户设定参数。我们来看看Hadoop源码是怎么获取客户端和管理员JVM参数的获取的:

  1. private static String getChildJavaOpts(JobConf jobConf, boolean isMapTask) {
  2. String userClasspath = "";
  3. String adminClasspath = "";
  4. if (isMapTask) {
  5. userClasspath =
  6. jobConf.get(
  7. JobConf.MAPRED_MAP_TASK_JAVA_OPTS,
  8. jobConf.get(
  9. JobConf.MAPRED_TASK_JAVA_OPTS,
  10. JobConf.DEFAULT_MAPRED_TASK_JAVA_OPTS)
  11. );
  12. adminClasspath =
  13. jobConf.get(
  14. MRJobConfig.MAPRED_MAP_ADMIN_JAVA_OPTS,
  15. MRJobConfig.DEFAULT_MAPRED_ADMIN_JAVA_OPTS);
  16. } else {
  17. userClasspath =
  18. jobConf.get(
  19. JobConf.MAPRED_REDUCE_TASK_JAVA_OPTS,
  20. jobConf.get(
  21. JobConf.MAPRED_TASK_JAVA_OPTS,
  22. JobConf.DEFAULT_MAPRED_TASK_JAVA_OPTS)
  23. );
  24. adminClasspath =
  25. jobConf.get(
  26. MRJobConfig.MAPRED_REDUCE_ADMIN_JAVA_OPTS,
  27. MRJobConfig.DEFAULT_MAPRED_ADMIN_JAVA_OPTS);
  28. }
  29.  
  30. // Add admin classpath first so it can be overridden by user.
  31. return adminClasspath + " " + userClasspath;
  32. }

  通过上面的代码,我们可以发现Hadoop是先获取管理员的JVM参数配置,然后连接客户端那边JVM参数的配置。这样如果管理员那边的配置在客户端那边也配置了,那么客户端这边的配置将会覆盖掉管理员那边的参数配置。所以我们可以修改源码,将 return adminClasspath + ” ” + userClasspath;修改为 return userClasspath + ” ” + adminClasspath;然后在mapred-site.xml文件做如下配置:

  1. <property>
  2. <name>mapreduce.admin.map.child.java.opts</name>
  3. <value>-Xmx1000m</value>
  4. </property>
  5. <property>
  6. <name>mapreduce.admin.reduce.child.java.opts</name>
  7. <value>-Xmx1000m</value>
  8. </property>

这样,我们就可以覆盖客户端那边的配置。
  

总结

  上面两种方法虽然能在一定程度上限制客户端使用堆的大小,但是这样的解决办法不是很好的!因为我们设定所有作业的堆大小都是1000M,但是实际情况下,很多作业不一定都用得到1000M;而且在一些情况下,有些作业用到的heap可能大于1000M,这样会使这样的作业出现OOM的问题。

Hadoop作业JVM堆大小设置优化 [转]的更多相关文章

  1. jvm详情——6、堆大小设置简单说明

    年轻代的设置很关键JVM中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理内存限制.32位系统下,一般限制在1.5G~2G:64 ...

  2. JVM堆内存设置和测试

    1. Java虚拟机内存结构 划分新生代和老年代,这样只在新生代分配内存,从而简化了新对象的分配.另外新生代和老年代使用不同的GC算法,可以更有效的清除不再需要的对象.从上图可以看出,JVM内存由yo ...

  3. 【转】JVM 堆内存设置原理

    堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...

  4. [转]JVM 堆内存设置原理

    堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...

  5. JVM 堆内存设置原理

    堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...

  6. JVM 堆内存设置原理(转)

    堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...

  7. JVM堆内存设置

    今天碰到了一个题目,讲的是关于堆内存的问题,题目如下   下面哪种情况会导致持久区jvm堆内存溢出? A.循环上万次的字符串处理 B.在一段代码内申请上百M甚至上G的内存 C.使用CGLib技术直接操 ...

  8. JVM堆内存参数优化,让性能飞起来

    堆内存是Java进程的重要组成部分,几乎所有与应用相关的内存空间都和堆有关.现在主要介绍与堆内存相关的参数设置,这些参数对Java虚拟机中非常重要的,也是对程序性能有着重要的影响.让你彻底脱离OOM内 ...

  9. java 调整jvm堆大小上限

    针对单个类,eclipse中调整jvm的运行参数,加上这么一句: -Xmx80m 即可把堆上限调整到80m. 关键字: BEA JRockit

随机推荐

  1. 使用ultramon调整任务栏高度

    取消锁定,调整任务栏的高度为一行图标的高度,然后再锁定即可.为啥程序没有默认设置?

  2. Win7x64_chromeX86_相关路径

    1. C:\Users\33\AppData\Local\Google 里面有2个文件夹:“Chrome”.“CrashReports” 2. C:\Program Files (x86)\Googl ...

  3. 关于inline-block 元素之间为何会产生间隔

    关于inline-block 元素之间为何会产生间隔 现象: <body> <input type="text"> <input type=" ...

  4. hibernate.properties与hibernate.cfg.xml 区别

    Hibernate的数据库连接信息是从配置文件中加载的. Hibernate的配置文件有两种形式:一种是XML格式的文件,一种是properties属性文件. 一)hibernate.cfg.xml ...

  5. css + html 小知识总结

    Html+CSS基础之Html 注:本文摘自慕课网http://www.imooc.com   HTML+CSS基础课程: 1. HTML是网页内容的载体.内容就是网页制作者放在页面上想要让用户浏览的 ...

  6. ios 开发之 Xcode6 No valid signing identities (i.e. certificate and private key pair) matching...

    之前的项目用证书真机测试过,我想再无证书Build,出现下面的报错提示! 下面的team我无法改成None!一点击None选的还是Unhonw name(JPGE28K3W9)这个是报错的关键 最后由 ...

  7. 笔试——JAVA相关

    1. String 和 StringBuffer 的区别(转自http://pengcqu.iteye.com/blog/487538) Java笔试题经常考到“String和StringBuffer ...

  8. Asp.net_Webservice返回json

    [WebMethod] public List<PictureManager> LoadPictureOne() { dataDataContext context = new dataD ...

  9. 20160805_Win7x64刻录CentOS6.4x64启动光盘

    使用的软件为:UltraISO.v.9.6.2.3059.exe Win7 x64 刻录 CentOS6.4 x64 启动盘,有提示错误信息. 网上查了一下,是 AHCI 的驱动没有安装.来到 联想t ...

  10. 【matlab】读写文件

    save('pqfile.mat','M'); ('E:\我的坚果云\pqfile.mat','M'); 其他: http://blog.csdn.net/iqizheng/article/detai ...