java - 通过REST提交EMR Yarn应用程序

标签 java hadoop classpath yarn amazon-emr

我在AWS的YARN中有一个Hadoop集群,向其提交了Spark应用程序。我通过REST请求进行工作,并按照本文档YARN REST API的规定提交XML。它对于常规群集非常有用。

我目前正在使用POC来处理EMR集群,而不是通常的POC,在这里我使用现有的REST命令,并简单地通过SSH与EMR的内部YARN通信,如下所示:Web access of internal EMR services。它适用于大多数REST命令,例如POST http://<rm http address:port>/ws/v1/cluster/apps/new-application,但是当我提交一个新应用程序时,它立即失败并报告找不到ApplicationMaster。

Log Type: stderr

Log Upload Time: Sun Feb 03 17:18:35 +0000 2019

Log Length: 88

Error: Could not find or load main class org.apache.spark.deploy.yarn.ApplicationMaster



我怀疑这以某种方式连接到了classpath,当我将所有jars(/ usr / lib / spark / jars / *)的EMR FS位置添加到REST提交应用程序节点的classpath标志时,它找到了ApplicationMaster但然后无法在核心实例中找到Jars,并显示以下奇怪的错误日志:

Log Type: stderr

Log Upload Time: Thu Jan 31 15:11:21 +0000 2019

Log Length: 89

Error: Could not find or load main class .usr.lib.spark.jars.datanucleus-core-3.2.10.jar



最不寻常的是它试图描述无法找到的jar的方式,而不是类。经过进一步调查,我发现了原因:将Java命令发送到Core实例时,它将类路径解析为其三个文件:java -server -classpath /usr/lib/spark/jars/datanucleus-api-jdo-3.2.6.jar /usr/lib/spark/jars/datanucleus-core-3.2.10.jar /usr/lib/spark/jars/datanucleus-rdbms-3.2.9.jar ...,因此尝试执行“/usr/lib/spark/jars/datanucleus-core-3.2” .10.jar”,就好像它是可运行的。问题是,如果我尝试将类路径更改为更具体,或者尝试删除它,则应用程序将因找不到ApplicationMaster而再次失败。

我发送到YARN的REST请求是:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<application-submission-context> 
<application-id>application_1549270910165_0001</application-id> 
<application-name> .... some name .....</application-name> 
<queue>default</queue> 
<priority>0</priority> 
<am-container-spec> 
<local-resources> 
    <entry>

 ....... MANY MANY RESOURCES ......

        </value>
    </entry>

</local-resources> 
<environment> 
<entry> 
<key>SPARK_YARN_STAGING_DIR</key> 
<value>..... staging directory in our HDFS ..... </value> 
</entry> 
<entry> 
<key>CLASSPATH</key> 
<value>$PWD:$PWD/__spark_conf__:$PWD/__spark_libs__/*:/usr/lib/spark/jars/*:/usr/lib/spark/yarn/lib/*:%HADOOP_CONF_DIR%:%HAOOP_COMMON_HOME%/share/hadoop/common/*:%HADOOP_COMMON_HOME%/share/hadoop/common/lib/*:%HADOOP_HDFS_HOME%/share/hadoop/hdfs/*:%HADOOP_HDFS_HOME%/share/hadoop/hdfs/lib/*:%HADOOP_YARN_HOME%/share/hadoop/yarn/*:%HADOOP_YARN_HOME%/share/hadoop/yarn/lib/*:%HADOOP_MAPRED_HOME%/share/hadoop/mapreduce/*:%HADOOP_MAPRED_HOME%/share/hadoop/mapreduce/lib/*:$PWD/__spark_conf__/__hadoop_conf__</value> 
</entry>
<entry>
<key>SPARK_USER</key>
<value>... user name ....</value>
</entry>
</environment>
<commands> 
<command>command=$JAVA_HOME/bin/java -classpath '/usr/lib/spark/jars/*' -server -Xmx5120M -Djava.io.tmpdir=$PWD/tmp '-XX:hashCode=0' '-Dlog4j.configuration=log4j-client.cfg' '-Dhdp.version=2.8.4' -Dspark.yarn.app.container.log.dir=&lt;LOG_DIR&gt; org.apache.spark.deploy.yarn.ApplicationMaster ... some jar and arguments ....  --properties-file $PWD/__spark_conf__/__spark_conf__.properties 1&gt; &lt;LOG_DIR&gt;/stdout 2&gt; &lt;LOG_DIR&gt;/stderr</command> 
</commands> 
</am-container-spec> 
<unmanaged-AM>false</unmanaged-AM> 
<max-app-attempts>1</max-app-attempts> 
<resource> 
<memory>5632</memory> 
<vCores>1</vCores> 
</resource> 
<application-type>SPARK</application-type> 
<keep-containers-across-application-attempts>false</keep-containers-across-application-attempts> 
<application-tags> 
<tag>.... product tag .....</tag> 
</application-tags> 
<log-aggregation-context/> 
<attempt-failures-validity-interval>1</attempt-failures-validity-interval> 
<reservation-id/> 
</application-submission-context>

我将不胜感激。

最佳答案

经过长时间的搜索,我发现应用程序无法加载类org.apache.spark.deploy.yarn.ApplicationMaster的原因是因为这不是EMR核心实例使用的ApplicationMaster的版本-它使用了org.apache.hadoop.yarn.applications.distributedshell.ApplicationMaster,它要求输入中的CLASSPATH段包括/usr/lib/hadoop-yarn/*。我更改了REST请求的输入XML中的两个参数,并成功启动了该参数。我仍然需要为EMR实现配置正确的CLASSPATH才能成功完成应用程序,但是这个问题的主要挑战已经解决。

更新:最终,我决定为EMR添加一个步骤并使用参数,实际上是一种更简单的处理方法。我向Maven依赖项添加了EMR AWS Java SDK:

<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-emr</artifactId>
    <version>1.11.486</version>
</dependency>

并添加以下代码:
AddJobFlowStepsResult result = emr.addJobFlowSteps(new AddJobFlowStepsRequest()
            .withJobFlowId(clusterId)
            .withSteps(new StepConfig()
                    .withName(name)
                    .withActionOnFailure(ActionOnFailure.CONTINUE)
                    .withHadoopJarStep(new HadoopJarStepConfig()
                            .withJar("command-runner.jar")
                            .withArgs(stepargs))));

stepargs来自我最初的REST请求,包括jar和要使用的文件-只需使用spark-submit即可:
List<String> stepargs = new ArrayList<String>();
stepargs.add("spark-submit");
stepargs.add("--class");
stepargs.add(mainClass);
stepargs.add("--deploy-mode");
stepargs.add("cluster");
stepargs.add("--master");
stepargs.add("yarn");
stepargs.add("--files");
stepargs.add(files);
stepargs.add("--jars");
stepargs.add(jars);
stepargs.add("--properties-file");
stepargs.add(confFileName);
stepargs.add(jar);
Iterator<String> itr = args.iterator();
while (itr.hasNext()) {
    String arg = itr.next();
    if (arg.equals("--arg")) {
        stepargs.add(itr.next());
    }
}

关于java - 通过REST提交EMR Yarn应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54513238/

相关文章:

hadoop - 使用Column header 读取CSV并将其加载到配置单元表中

运行包含库 jar 的 jar 时出现 Java NoClassDefFoundError

java - 强制 java jar 在 EMR 上不使用类路径包

java - java中10000 * 400点的热图

hadoop - hbase 批量加载中的奇怪行为

hadoop - 如何映射减少顺序数据,其中 Kn+1->Vn+1 = f(Kn->Vn)?

java - NoClassDefFoundError : groovy/lang/binding

java - 带进度条的 Swing 启动画面

java - libsvm java 中的交叉验证准确性

java - 与jms交换的接口(interface)