Repository: oozie Updated Branches: refs/heads/master fb6f4305f -> 94306b4dc OOZIE-1958 address duplication of env variables in oozie.launcher.yarn.app.mapreduce.am.env when running with uber mode (ryota) Project: http://git-wip-us.apache.org/repos/asf/oozie/repo Commit: http://git-wip-us.apache.org/repos/asf/oozie/commit/94306b4d Tree: http://git-wip-us.apache.org/repos/asf/oozie/tree/94306b4d Diff: http://git-wip-us.apache.org/repos/asf/oozie/diff/94306b4d Branch: refs/heads/master Commit: 94306b4dcc3447df9c8b84c5c89977af71076898 Parents: fb6f430 Author: egashira Authored: Mon Aug 11 12:39:30 2014 -0700 Committer: egashira Committed: Mon Aug 11 12:39:30 2014 -0700 ---------------------------------------------------------------------- .../oozie/action/hadoop/JavaActionExecutor.java | 142 +++++++++++++------ .../action/hadoop/TestJavaActionExecutor.java | 69 +++++++++ release-log.txt | 1 + 3 files changed, 171 insertions(+), 41 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/oozie/blob/94306b4d/core/src/main/java/org/apache/oozie/action/hadoop/JavaActionExecutor.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/oozie/action/hadoop/JavaActionExecutor.java b/core/src/main/java/org/apache/oozie/action/hadoop/JavaActionExecutor.java index 94b55cf..7f4d473 100644 --- a/core/src/main/java/org/apache/oozie/action/hadoop/JavaActionExecutor.java +++ b/core/src/main/java/org/apache/oozie/action/hadoop/JavaActionExecutor.java @@ -93,7 +93,7 @@ public class JavaActionExecutor extends ActionExecutor { public final static String MAX_EXTERNAL_STATS_SIZE = "oozie.external.stats.max.size"; public static final String ACL_VIEW_JOB = "mapreduce.job.acl-view-job"; public static final String ACL_MODIFY_JOB = "mapreduce.job.acl-modify-job"; - private static final String HADOOP_YARN_UBER_MODE = "mapreduce.job.ubertask.enable"; + public static final String HADOOP_YARN_UBER_MODE = "mapreduce.job.ubertask.enable"; public static final String HADOOP_MAP_MEMORY_MB = "mapreduce.map.memory.mb"; public static final String HADOOP_CHILD_JAVA_OPTS = "mapred.child.java.opts"; public static final String HADOOP_MAP_JAVA_OPTS = "mapreduce.map.java.opts"; @@ -270,56 +270,116 @@ public class JavaActionExecutor extends ActionExecutor { void updateConfForUberMode(Configuration launcherConf) { - // memory.mb - int launcherMapMemoryMB = launcherConf.getInt(HADOOP_MAP_MEMORY_MB, 1536); - int amMemoryMB = launcherConf.getInt(YARN_AM_RESOURCE_MB, 1536); - // YARN_MEMORY_MB_MIN to provide buffer. - // suppose launcher map aggressively use high memory, need some headroom for AM - int memoryMB = Math.max(launcherMapMemoryMB, amMemoryMB) + YARN_MEMORY_MB_MIN; - // limit to 4096 in case of 32 bit - if(launcherMapMemoryMB < 4096 && amMemoryMB < 4096 && memoryMB > 4096){ - memoryMB = 4096; - } - launcherConf.setInt(YARN_AM_RESOURCE_MB, memoryMB); - - // We already made mapred.child.java.opts and mapreduce.map.java.opts equal, so just start with one of them - String launcherMapOpts = launcherConf.get(HADOOP_MAP_JAVA_OPTS, ""); - String amChildOpts = launcherConf.get(YARN_AM_COMMAND_OPTS); - StringBuilder optsStr = new StringBuilder(); - int heapSizeForMap = extractHeapSizeMB(launcherMapOpts); - int heapSizeForAm = extractHeapSizeMB(amChildOpts); - int heapSize = Math.max(heapSizeForMap, heapSizeForAm) + YARN_MEMORY_MB_MIN; - // limit to 3584 in case of 32 bit - if(heapSizeForMap < 4096 && heapSizeForAm < 4096 && heapSize > 3584) { - heapSize = 3584; - } - if (amChildOpts != null) { - optsStr.append(amChildOpts); - } - optsStr.append(" ").append(launcherMapOpts.trim()); - if (heapSize > 0) { - // append calculated total heap size to the end - optsStr.append(" ").append("-Xmx").append(heapSize).append("m"); - } - launcherConf.set(YARN_AM_COMMAND_OPTS, optsStr.toString().trim()); - // child.env + boolean hasConflictEnv = false; String launcherMapEnv = launcherConf.get(HADOOP_MAP_JAVA_ENV); if (launcherMapEnv == null) { launcherMapEnv = launcherConf.get(HADOOP_CHILD_JAVA_ENV); } - String envForAm = launcherConf.get(YARN_AM_ENV); + String amEnv = launcherConf.get(YARN_AM_ENV); StringBuffer envStr = new StringBuffer(); - if (envForAm != null) { - envStr.append(envForAm); + HashMap> amEnvMap = null; + HashMap> launcherMapEnvMap = null; + if (amEnv != null) { + envStr.append(amEnv); + amEnvMap = populateEnvMap(amEnv); } if (launcherMapEnv != null) { - if (envForAm != null) { - envStr.append(","); + launcherMapEnvMap = populateEnvMap(launcherMapEnv); + if (amEnvMap != null) { + Iterator envKeyItr = launcherMapEnvMap.keySet().iterator(); + while (envKeyItr.hasNext()) { + String envKey = envKeyItr.next(); + if (amEnvMap.containsKey(envKey)) { + List amValList = amEnvMap.get(envKey); + List launcherValList = launcherMapEnvMap.get(envKey); + Iterator valItr = launcherValList.iterator(); + while (valItr.hasNext()) { + String val = valItr.next(); + if (!amValList.contains(val)) { + hasConflictEnv = true; + break; + } + else { + valItr.remove(); + } + } + if (launcherValList.isEmpty()) { + envKeyItr.remove(); + } + } + } + } + } + if (hasConflictEnv) { + launcherConf.setBoolean(HADOOP_YARN_UBER_MODE, false); + } + else { + if (launcherMapEnvMap != null) { + for (String key : launcherMapEnvMap.keySet()) { + List launcherValList = launcherMapEnvMap.get(key); + for (String val : launcherValList) { + if (envStr.length() > 0) { + envStr.append(","); + } + envStr.append(key).append("=").append(val); + } + } + } + + launcherConf.set(YARN_AM_ENV, envStr.toString()); + + // memory.mb + int launcherMapMemoryMB = launcherConf.getInt(HADOOP_MAP_MEMORY_MB, 1536); + int amMemoryMB = launcherConf.getInt(YARN_AM_RESOURCE_MB, 1536); + // YARN_MEMORY_MB_MIN to provide buffer. + // suppose launcher map aggressively use high memory, need some + // headroom for AM + int memoryMB = Math.max(launcherMapMemoryMB, amMemoryMB) + YARN_MEMORY_MB_MIN; + // limit to 4096 in case of 32 bit + if (launcherMapMemoryMB < 4096 && amMemoryMB < 4096 && memoryMB > 4096) { + memoryMB = 4096; + } + launcherConf.setInt(YARN_AM_RESOURCE_MB, memoryMB); + + // We already made mapred.child.java.opts and + // mapreduce.map.java.opts equal, so just start with one of them + String launcherMapOpts = launcherConf.get(HADOOP_MAP_JAVA_OPTS, ""); + String amChildOpts = launcherConf.get(YARN_AM_COMMAND_OPTS); + StringBuilder optsStr = new StringBuilder(); + int heapSizeForMap = extractHeapSizeMB(launcherMapOpts); + int heapSizeForAm = extractHeapSizeMB(amChildOpts); + int heapSize = Math.max(heapSizeForMap, heapSizeForAm) + YARN_MEMORY_MB_MIN; + // limit to 3584 in case of 32 bit + if (heapSizeForMap < 4096 && heapSizeForAm < 4096 && heapSize > 3584) { + heapSize = 3584; + } + if (amChildOpts != null) { + optsStr.append(amChildOpts); + } + optsStr.append(" ").append(launcherMapOpts.trim()); + if (heapSize > 0) { + // append calculated total heap size to the end + optsStr.append(" ").append("-Xmx").append(heapSize).append("m"); + } + launcherConf.set(YARN_AM_COMMAND_OPTS, optsStr.toString().trim()); + } + } + + private HashMap> populateEnvMap(String input) { + HashMap> envMaps = new HashMap>(); + String[] envEntries = input.split(","); + for (String envEntry : envEntries) { + String[] envKeyVal = envEntry.split("="); + String envKey = envKeyVal[0].trim(); + List valList = envMaps.get(envKey); + if (valList == null) { + valList = new ArrayList(); } - envStr.append(launcherMapEnv); + valList.add(envKeyVal[1].trim()); + envMaps.put(envKey, valList); } - launcherConf.set(YARN_AM_ENV, envStr.toString()); + return envMaps; } public int extractHeapSizeMB(String input) { http://git-wip-us.apache.org/repos/asf/oozie/blob/94306b4d/core/src/test/java/org/apache/oozie/action/hadoop/TestJavaActionExecutor.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/oozie/action/hadoop/TestJavaActionExecutor.java b/core/src/test/java/org/apache/oozie/action/hadoop/TestJavaActionExecutor.java index 72a137c..17c5fd9 100644 --- a/core/src/test/java/org/apache/oozie/action/hadoop/TestJavaActionExecutor.java +++ b/core/src/test/java/org/apache/oozie/action/hadoop/TestJavaActionExecutor.java @@ -1788,6 +1788,75 @@ public class TestJavaActionExecutor extends ActionExecutorTestCase { assertEquals("A=foo,B=bar", launcherConf.get(JavaActionExecutor.YARN_AM_ENV)); } + public void testUpdateConfForUberModeWithEnvDup() throws Exception { + + Services.get().getConf().setBoolean("oozie.action.launcher.mapreduce.job.ubertask.enable", true); + + Element actionXml1 = XmlUtils.parseXml("" + "" + getJobTrackerUri() + "" + + "" + getNameNodeUri() + "" + "" + + "oozie.launcher.yarn.app.mapreduce.am.env" + + "JAVA_HOME=/home/blah/java/jdk64/current,A=foo,B=bar" + + "oozie.launcher.mapreduce.map.env" + + "JAVA_HOME=/home/blah/java/jdk64/latest,C=blah" + "" + + "MAIN-CLASS" + ""); + JavaActionExecutor ae = new JavaActionExecutor(); + XConfiguration protoConf = new XConfiguration(); + protoConf.set(WorkflowAppService.HADOOP_USER, getTestUser()); + + WorkflowJobBean wf = createBaseWorkflow(protoConf, "action"); + WorkflowActionBean action = (WorkflowActionBean) wf.getActions().get(0); + action.setType(ae.getType()); + + Context context = new Context(wf, action); + JobConf launcherConf = new JobConf(); + launcherConf = ae.createLauncherConf(getFileSystem(), context, action, actionXml1, launcherConf); + + // uber mode should be disabled since JAVA_HOME points to different paths in am.evn and map.env + assertEquals("false", launcherConf.get(JavaActionExecutor.HADOOP_YARN_UBER_MODE)); + + // testing complicated env setting case + Element actionXml2 = XmlUtils.parseXml("" + "" + getJobTrackerUri() + "" + + "" + getNameNodeUri() + "" + "" + "" + + "oozie.launcher.yarn.app.mapreduce.am.env" + + "LD_LIBRARY_PATH=$HADOOP_HOME_1/lib/native/`$JAVA_HOME/bin/java -d32 -version;" + + "if [ $? -eq 0 ]; then echo Linux-i386-32; else echo Linux-amd64-64;fi`" + + "" + "oozie.launcher.mapreduce.map.env" + + "LD_LIBRARY_PATH=$HADOOP_HOME_2/lib/native/`$JAVA_HOME/bin/java -d32 -version;" + + "if [ $? -eq 0 ]; then echo Linux-i386-32; else echo Linux-amd64-64;fi`" + + "" + "MAIN-CLASS" + ""); + + launcherConf = ae.createLauncherConf(getFileSystem(), context, action, actionXml2, launcherConf); + + // uber mode should be disabled since LD_LIBRARY_PATH is different in am.evn and map.env + assertEquals("false", launcherConf.get(JavaActionExecutor.HADOOP_YARN_UBER_MODE)); + + Element actionXml3 = XmlUtils + .parseXml("" + + "" + + getJobTrackerUri() + + "" + + "" + + getNameNodeUri() + + "" + + "" + + "oozie.launcher.yarn.app.mapreduce.am.env" + + "JAVA_HOME=/home/blah/java/jdk64/current,PATH=A,PATH=B" + + "oozie.launcher.mapreduce.map.env" + + "JAVA_HOME=/home/blah/java/jdk64/current,PATH=A" + + "" + "MAIN-CLASS" + ""); + + launcherConf = ae.createBaseHadoopConf(context, actionXml3); + launcherConf = ae.createLauncherConf(getFileSystem(), context, action, actionXml3, launcherConf); + + // uber mode should be enabled since JAVA_HOME is the same, and PATH doesn't conflict + assertEquals("true", launcherConf.get(JavaActionExecutor.HADOOP_YARN_UBER_MODE)); + + // JAVA_HOME, PATH=A duplication is removed + String a = launcherConf.get(JavaActionExecutor.YARN_AM_ENV); + assertEquals("JAVA_HOME=/home/blah/java/jdk64/current,PATH=A,PATH=B", + launcherConf.get(JavaActionExecutor.YARN_AM_ENV)); + } + public void testUpdateConfForUberModeForJavaOpts() throws Exception { Services.get().getConf().setBoolean("oozie.action.launcher.mapreduce.job.ubertask.enable", true); http://git-wip-us.apache.org/repos/asf/oozie/blob/94306b4d/release-log.txt ---------------------------------------------------------------------- diff --git a/release-log.txt b/release-log.txt index 80927e9..b84e96a 100644 --- a/release-log.txt +++ b/release-log.txt @@ -4,6 +4,7 @@ OOZIE-1943 Bump up trunk to 4.2.0-SNAPSHOT (bzhang) -- Oozie 4.1.0 release (4.1 - unreleased) +OOZIE-1958 address duplication of env variables in oozie.launcher.yarn.app.mapreduce.am.env when running with uber mode (ryota) OOZIE-1920 Capture Output for SSH Action doesn't work (Richard Williams via rkanter) OOZIE-1961 Remove requireJavaVersion from enforcer rules (lars_francke via rkanter) OOZIE-1883 hostnameFilter has invalid url-pattern (dvillegas via rkanter)