Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
ml.shifu.guagua.yarn.util.YarnUtils Maven / Gradle / Ivy
/*
* Copyright [2013-2014] PayPal Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ml.shifu.guagua.yarn.util;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import ml.shifu.guagua.yarn.GuaguaYarnConstants;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.mapreduce.MRJobConfig;
import org.apache.hadoop.yarn.api.ApplicationConstants;
import org.apache.hadoop.yarn.api.ApplicationConstants.Environment;
import org.apache.hadoop.yarn.api.records.ApplicationId;
import org.apache.hadoop.yarn.api.records.LocalResource;
import org.apache.hadoop.yarn.api.records.LocalResourceType;
import org.apache.hadoop.yarn.api.records.LocalResourceVisibility;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.util.ConverterUtils;
import org.apache.hadoop.yarn.util.Records;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Splitter;
import com.google.common.collect.Maps;
/**
* {@link YarnUtils} is yarn-related helper class.
*/
public final class YarnUtils {
private static final Logger LOG = LoggerFactory.getLogger(YarnUtils.class);
public static final String GUAGUA_YARN_TMP = "tmp";
/** Private constructor, this is a utility class only */
private YarnUtils() {
}
/**
* Build local resources including main app jar, lib jars, log4j.properties and guagua-conf.xml.
*/
public static Map getLocalResourceMap(Configuration conf, ApplicationId appId)
throws IOException {
Map localResources = Maps.newHashMap();
FileSystem fs = FileSystem.get(conf);
// yarn app jar
addFileToResourceMap(localResources, fs,
getPathForResource(fs, conf.get(GuaguaYarnConstants.GUAGUA_YARN_APP_JAR), appId));
try {
addFileToResourceMap(localResources, fs,
getPathForResource(fs, GuaguaYarnConstants.GUAGUA_LOG4J_PROPERTIES, appId));
} catch (FileNotFoundException e) {
LOG.warn("log4j.properties does not exist!");
}
addFileToResourceMap(localResources, fs, getPathForResource(fs, GuaguaYarnConstants.GUAGUA_CONF_FILE, appId));
// Libs
String libs = conf.get(GuaguaYarnConstants.GUAGUA_YARN_APP_LIB_JAR);
if(StringUtils.isNotEmpty(libs)) {
for(String jar: Splitter.on(GuaguaYarnConstants.GUAGUA_APP_LIBS_SEPERATOR).split(libs)) {
addFileToResourceMap(localResources, fs, getPathForResource(fs, jar.trim(), appId));
}
}
return localResources;
}
/**
* Return java command according to main class, vm args, program args and memory settings.
*/
public static List getCommand(String mainClass, String vmArgs, String programArgs, String memory) {
List commands = new ArrayList(1);
commands.add(getCommandBase(mainClass, vmArgs, programArgs, memory).toString());
LOG.info("commands:{}", commands);
return commands;
}
private static StringBuilder getCommandBase(String mainClass, String vmArgs, String programArgs, String memory) {
List commands = new ArrayList(8);
commands.add("exec");
commands.add(Environment.JAVA_HOME.$() + File.separator + "bin" + File.separator + "java");
commands.add("-Xms" + memory + "m");
commands.add("-Xmx" + memory + "m");
if(vmArgs != null) {
commands.add(vmArgs);
}
commands.add("-cp .:${CLASSPATH}");
commands.add(mainClass);
if(programArgs != null) {
commands.add(programArgs);
}
commands.add("1> " + ApplicationConstants.LOG_DIR_EXPANSION_VAR + File.separator + ApplicationConstants.STDOUT);
commands.add("2> " + ApplicationConstants.LOG_DIR_EXPANSION_VAR + File.separator + ApplicationConstants.STDERR);
StringBuilder sb = new StringBuilder(200);
for(String cmd: commands) {
sb.append(cmd).append(" ");
}
return sb;
}
/**
* Populate the environment string map to be added to the environment vars in a remote execution container.
*
* @param env
* the map of env var values.
* @param conf
* the Configuration to pull values from.
*/
public static void addLocalClasspathToEnv(final Map env, final Configuration conf) {
StringBuilder classPathEnv = new StringBuilder(Environment.CLASSPATH.$());
// add current folder
classPathEnv.append(File.pathSeparatorChar).append("./*");
// add yarn app classpath
for(String cpEntry: conf.getStrings(YarnConfiguration.YARN_APPLICATION_CLASSPATH,
YarnConfiguration.DEFAULT_YARN_APPLICATION_CLASSPATH)) {
classPathEnv.append(File.pathSeparatorChar).append(cpEntry.trim());
}
for(String jar: conf.getStrings(MRJobConfig.MAPREDUCE_APPLICATION_CLASSPATH,
org.apache.hadoop.util.StringUtils.getStrings(MRJobConfig.DEFAULT_MAPREDUCE_APPLICATION_CLASSPATH))) {
classPathEnv.append(File.pathSeparatorChar).append(jar.trim());
}
// add the runtime classpath needed for tests to work
if(conf.getBoolean(YarnConfiguration.IS_MINI_YARN_CLUSTER, false)) {
classPathEnv.append(File.pathSeparatorChar).append(Environment.CLASSPATH.$());
}
// add guagua app jar file
String path = getFileName(conf.get(GuaguaYarnConstants.GUAGUA_YARN_APP_JAR));
classPathEnv.append(GuaguaYarnConstants.CURRENT_DIR).append(path).append(File.pathSeparatorChar);
// Any libraries we may have copied over?
String libs = conf.get(GuaguaYarnConstants.GUAGUA_YARN_APP_LIB_JAR);
if(StringUtils.isNotEmpty(libs)) {
for(String jar: Splitter.on(GuaguaYarnConstants.GUAGUA_APP_LIBS_SEPERATOR).split(libs)) {
classPathEnv.append(GuaguaYarnConstants.CURRENT_DIR).append(getFileName(jar.trim()))
.append(File.pathSeparatorChar);
}
}
// add log4j
classPathEnv.append(GuaguaYarnConstants.CURRENT_DIR).append(GuaguaYarnConstants.GUAGUA_LOG4J_PROPERTIES)
.append(File.pathSeparatorChar);
// add guagua-conf.xml
classPathEnv.append(GuaguaYarnConstants.CURRENT_DIR).append(GuaguaYarnConstants.GUAGUA_CONF_FILE);
env.put(Environment.CLASSPATH.toString(), classPathEnv.toString());
}
private static String getFileName(String string) {
return new Path(string).getName();
}
/**
* Get path to store local resources on hdfs.
*/
public static Path getPathForResource(FileSystem fs, String loc, ApplicationId appId) {
return new Path(getAppDirectory(fs, appId), getFileName(loc));
}
/**
* Working folder to store jars, files and other resources
*/
public static Path getAppDirectory(FileSystem fs, ApplicationId appId) {
return fs.makeQualified(new Path(
new Path(File.separator + GUAGUA_YARN_TMP, GuaguaYarnConstants.GUAGUA_HDFS_DIR), appId.toString()));
}
/**
* Copy batch of resources to hdfs app directory for master and containers.
*/
public static void copyLocalResourcesToFs(Configuration conf, ApplicationId appId) throws IOException {
FileSystem fs = FileSystem.get(conf);
Path appDir = getAppDirectory(fs, appId);
// copy yarn app jar
String appJar = conf.get(GuaguaYarnConstants.GUAGUA_YARN_APP_JAR);
copyToFs(conf, appJar, new Path(appDir, getFileName(appJar)).toString());
// copy guagua-conf.xml: done one export method
// copyToFs(conf, appJar, new Path(tempDir, GuaguaYarnConstants.GUAGUA_CONF_FILE).toString());
// Copy all lib jars
String libs = conf.get(GuaguaYarnConstants.GUAGUA_YARN_APP_LIB_JAR);
if(StringUtils.isNotEmpty(libs)) {
for(String jar: Splitter.on(GuaguaYarnConstants.GUAGUA_APP_LIBS_SEPERATOR).split(libs)) {
copyToFs(conf, jar, new Path(appDir, getFileName(jar.trim())).toString());
}
}
}
private static void copyToFs(Configuration conf, String local, String remote) throws IOException {
FileSystem fs = FileSystem.get(conf);
Path src = new Path(local);
Path dst = fs.makeQualified(new Path(remote));
fs.copyFromLocalFile(false, true, src, dst);
}
/**
* Boilerplate to add a file to the local resources..
*
* @param localResources
* the LocalResources map to populate.
* @param fs
* handle to the HDFS file system.
* @param target
* the file to send to the remote container.
*/
public static void addFileToResourceMap(Map localResources, FileSystem fs, Path target)
throws IOException {
LocalResource resource = Records.newRecord(LocalResource.class);
FileStatus destStatus = fs.getFileStatus(target);
resource.setResource(ConverterUtils.getYarnUrlFromURI(target.toUri()));
resource.setSize(destStatus.getLen());
resource.setTimestamp(destStatus.getModificationTime());
resource.setType(LocalResourceType.FILE); // use FILE, even for jars!
resource.setVisibility(LocalResourceVisibility.APPLICATION);
localResources.put(target.getName(), resource);
LOG.info("Registered file in LocalResources :{} ", target);
}
/**
* Copy local file to a named-file in remote FS
*/
public static void copyLocalResourceToFs(String src, String dst, Configuration conf, ApplicationId appId)
throws IOException {
FileSystem fs = FileSystem.get(conf);
Path tempDir = getAppDirectory(fs, appId);
copyToFs(conf, src, new Path(tempDir, dst).toString());
}
/**
* Export our populated Configuration as an XML file to be used by the ApplicationMaster's exec container, and
* register it with LocalResources.
*
* @param conf
* the current Configuration object to be published.
* @param appId
* the ApplicationId to stamp this app's base HDFS resources dir.
*/
public static void exportGuaguaConfiguration(Configuration conf, ApplicationId appId) throws IOException {
FileSystem fs = FileSystem.get(conf);
Path hdfsConfPath = new Path(getAppDirectory(fs, appId), GuaguaYarnConstants.GUAGUA_CONF_FILE);
FSDataOutputStream fos = null;
try {
fos = FileSystem.get(conf).create(hdfsConfPath, true);
conf.writeXml(fos);
fos.flush();
} finally {
if(null != fos) {
fos.close();
}
}
}
}