Hadoop作业JVM堆大小设置优化 [转]
前段时间,公司Hadoop集群整体的负载很高,查了一下原因,发现原来是客户端那边在每一个作业上擅自配置了很大的堆空间,从而导致集群负载很高。下面我就来讲讲怎么来现在客户端那边的JVM堆大小的设置。
我们知道,在mapred-site.xml配置文件里面有个mapred.child.java.opts配置,专门来配置一些诸如堆、垃圾回收之类的。看下下面的配置:
<property>
<name>mapred.child.java.opts</name>
<value>-Xmx200m</value>
<description>Java opts for the task tracker child processes.
The following symbol, if present, will be interpolated: @taskid@ is
replaced by current TaskID. Any other occurrences of '@' will go unchanged.
For example, to enable verbose gc logging to a file named for the taskid in
/tmp and to set the heap maximum to be a gigabyte, pass a 'value' of:-Xmx1024m -verbose:gc -Xloggc:/tmp/@taskid@.gc
The configuration variable mapred.child.ulimit can be used to control the
maximum virtual memory of the child processes.
</description>
</property>
默认情况下,-Xmx都是配置200m的,但是在实际情况下,这个显然是不够用的,所以导致客户端那边会设置更大的值。那怎么来限制用户随便设置Xmx的值呢?有下面两种方法:
一、可以自己定义一个变量,比如如下:
<property>
<name>mapred.task.java.opts</name>
<value>-Xmx2000m</value>
</property> <property>
<name>mapred.child.java.opts</name>
<value>${mapred.task.java.opts} -Xmx1000m</value>
<final>true</final>
</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了。同样的道理,其他想覆盖的参数我们也可以写到后面。
<property>
<name>mapred.map.child.java.opts</name>
<value>
-Xmx512M
</value>
</property> <property>
<name>mapred.reduce.child.java.opts</name>
<value>
-Xmx1024M
</value>
</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参数的获取的:
private static String getChildJavaOpts(JobConf jobConf, boolean isMapTask) {
String userClasspath = "";
String adminClasspath = "";
if (isMapTask) {
userClasspath =
jobConf.get(
JobConf.MAPRED_MAP_TASK_JAVA_OPTS,
jobConf.get(
JobConf.MAPRED_TASK_JAVA_OPTS,
JobConf.DEFAULT_MAPRED_TASK_JAVA_OPTS)
);
adminClasspath =
jobConf.get(
MRJobConfig.MAPRED_MAP_ADMIN_JAVA_OPTS,
MRJobConfig.DEFAULT_MAPRED_ADMIN_JAVA_OPTS);
} else {
userClasspath =
jobConf.get(
JobConf.MAPRED_REDUCE_TASK_JAVA_OPTS,
jobConf.get(
JobConf.MAPRED_TASK_JAVA_OPTS,
JobConf.DEFAULT_MAPRED_TASK_JAVA_OPTS)
);
adminClasspath =
jobConf.get(
MRJobConfig.MAPRED_REDUCE_ADMIN_JAVA_OPTS,
MRJobConfig.DEFAULT_MAPRED_ADMIN_JAVA_OPTS);
} // Add admin classpath first so it can be overridden by user.
return adminClasspath + " " + userClasspath;
}
通过上面的代码,我们可以发现Hadoop是先获取管理员的JVM参数配置,然后连接客户端那边JVM参数的配置。这样如果管理员那边的配置在客户端那边也配置了,那么客户端这边的配置将会覆盖掉管理员那边的参数配置。所以我们可以修改源码,将 return adminClasspath + ” ” + userClasspath;修改为 return userClasspath + ” ” + adminClasspath;然后在mapred-site.xml文件做如下配置:
<property>
<name>mapreduce.admin.map.child.java.opts</name>
<value>-Xmx1000m</value>
</property>
<property>
<name>mapreduce.admin.reduce.child.java.opts</name>
<value>-Xmx1000m</value>
</property>
这样,我们就可以覆盖客户端那边的配置。
总结
上面两种方法虽然能在一定程度上限制客户端使用堆的大小,但是这样的解决办法不是很好的!因为我们设定所有作业的堆大小都是1000M,但是实际情况下,很多作业不一定都用得到1000M;而且在一些情况下,有些作业用到的heap可能大于1000M,这样会使这样的作业出现OOM的问题。
Hadoop作业JVM堆大小设置优化 [转]的更多相关文章
- jvm详情——6、堆大小设置简单说明
年轻代的设置很关键JVM中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理内存限制.32位系统下,一般限制在1.5G~2G:64 ...
- JVM堆内存设置和测试
1. Java虚拟机内存结构 划分新生代和老年代,这样只在新生代分配内存,从而简化了新对象的分配.另外新生代和老年代使用不同的GC算法,可以更有效的清除不再需要的对象.从上图可以看出,JVM内存由yo ...
- 【转】JVM 堆内存设置原理
堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...
- [转]JVM 堆内存设置原理
堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...
- JVM 堆内存设置原理
堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...
- JVM 堆内存设置原理(转)
堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...
- JVM堆内存设置
今天碰到了一个题目,讲的是关于堆内存的问题,题目如下 下面哪种情况会导致持久区jvm堆内存溢出? A.循环上万次的字符串处理 B.在一段代码内申请上百M甚至上G的内存 C.使用CGLib技术直接操 ...
- JVM堆内存参数优化,让性能飞起来
堆内存是Java进程的重要组成部分,几乎所有与应用相关的内存空间都和堆有关.现在主要介绍与堆内存相关的参数设置,这些参数对Java虚拟机中非常重要的,也是对程序性能有着重要的影响.让你彻底脱离OOM内 ...
- java 调整jvm堆大小上限
针对单个类,eclipse中调整jvm的运行参数,加上这么一句: -Xmx80m 即可把堆上限调整到80m. 关键字: BEA JRockit
随机推荐
- 容易混淆的url src href
新手刚学习的时候会分不清 url src href这些,不知道什么情况下应该用哪个.现在让我来理一理. url 统一资源定位符是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网 ...
- 百度之星复赛Astar Round3
拍照 树状数组(SB了).求出静止状态下,每个点能看到多少个向右开的船c1[i],多少个向左开的船c2[i]. max{c1[i] + c2[j], (满足i <= j) }即为答案.从后往前 ...
- Android广播BroadcastReceiver 一
Android 系统里定义了各种各样的广播,如电池的使用状态,电话的接收和短信的接收,开机启动都会产生一个广播.当然用户也可以自定义自己的广播. 既然说到广播,那么必定有一个广播发送者,以及广播接收器 ...
- LA 5135 Mining Your Own Business
求出 bcc 后再……根据大白书上的思路即可. 然后我用的是自定义的 stack 类模板: #include<cstdio> #include<cstring> #includ ...
- Freemarker 浅析 (zhuan)
http://blog.csdn.net/marksinoberg/article/details/52006311 ***************************************** ...
- 转!!java中的内部类总结
java内部类 内部类不是很好理解,但说白了其实也就是一个类中还包含着另外一个类 如同一个人是由大脑.肢体.器官等身体结果组成,而内部类相当于其中的某个器官之一,例如心脏:它也有自己的属性和行为(血液 ...
- phalcon: (非官方)简单的多模块
phalcon: [非官方]多模块 配合router使用 例如:我的模块叫做: home 入口文件增加引入: use Phalcon\Mvc\Router; 在自动引入前面增加,自动引入命名空间: / ...
- Java软件工程师全栈技能
1.前端基础技能,掌握html.js.css,会用jquery.bootstrap. 2.前端技能升级,会用echart.BMap等等. 3.前端高级技能,熟练使用angularjs等等. 4.服务端 ...
- java main函数
public static void main(String[] args)[String args[]]也对 1)public :公共的权限最大,在任何情况下都可以访问. 原因:为了保证java虚拟 ...
- Unity3D在Windows的全屏和跨屏(双屏)方案
方案1 unity中2个摄像机场景显示在两个显示器屏幕上(一个窗口跨屏) 1.设置场景中的两个摄像机 摄像机1 摄像机2 2.设置发布的平台及分辨率 3.全屏运行游戏,没有标题栏还可以通过-popup ...