Amazon Elastic MapReduce上的Spark Java错误NoClassDefFoundError

Amazon Elastic MapReduce上的Spark Java错误NoClassDefFoundError,java,mapreduce,apache-spark,emr,Java,Mapreduce,Apache Spark,Emr,我试图在Amazon的Elastic MapReduce(EMR)上实现并运行一个Spark应用程序。到目前为止,我已经能够使用以下链接通过“Spark安装”引导操作部署和运行集群: s3://elasticmapreduce/samples/spark/0.8.1/install-spark-shark.sh 可以从internet方向访问脚本 为了将.jar应用程序上载到集群,我创建了一个步骤配置,如下所示: HadoopJarStepConfig customConfig = new H

我试图在Amazon的Elastic MapReduce(EMR)上实现并运行一个Spark应用程序。到目前为止,我已经能够使用以下链接通过“Spark安装”引导操作部署和运行集群:

s3://elasticmapreduce/samples/spark/0.8.1/install-spark-shark.sh

可以从internet方向访问脚本

为了将.jar应用程序上载到集群,我创建了一个步骤配置,如下所示:

 HadoopJarStepConfig customConfig = new HadoopJarStepConfig()
                 .withJar("s3://mybucket/SparkApp.jar")
                 .withMainClass("SparkApp.java");

 StepConfig customJarStep = new StepConfig()
                 .withName("Run custom jar")                                                                                    
                 .withActionOnFailure(ActionOnFailure.CONTINUE)
                 .withHadoopJarStep(customConfig);
最后,下面的代码显示了从Spark团队提供的wordcount示例中提取的实际Spark应用程序(对于0.8.1版本)。正如您可能注意到的,代码导入不同的spark库以运行应用程序。图书馆包括:

spark-core_2.9.3-0.8.1-Cubating.jar (及) scala-library-2.9.3.jar

导入scala.Tuple2;
导入org.apache.spark.api.java.javapairdd;
导入org.apache.spark.api.java.JavaRDD;
导入org.apache.spark.api.java.JavaSparkContext;
导入org.apache.spark.api.java.function.FlatMapFunction;
导入org.apache.spark.api.java.function.Function2;
导入org.apache.spark.api.java.function.PairFunction;
导入java.util.array;
导入java.util.List;
公共级SparkApp{
公共静态void main(字符串[]args)引发异常{
JavaSparkContext ctx=新的JavaSparkContext(“本地”、“JavaWordCount”,
System.getenv(“SPARK_HOME”)、System.getenv(“SPARK_示例_JAR”);
javarddlines=ctx.textFile(“c3://murquiabucket/wordcount.txt”,1);
JavaRDD words=lines.flatMap(新的flatMap函数(){
公共Iterable调用(字符串s){
返回数组.asList(s.split(“”);
}
});
javapairdd ones=words.map(新PairFunction(){
公共元组2调用(字符串s){
返回新的Tuple2(s,1);
}
});
javapairdd counts=one.reduceByKey(新函数2(){
公共整数调用(整数i1、整数i2){
返回i1+i2;
}
});
列表输出=counts.collect();
for(Tuple2 tuple:output){
System.out.println(tuple.\u 1+“:”+tuple.\u 2);
}
系统出口(0);
}
}
当我试图在EMR集群中执行jar(我制作了一个胖jar来嵌入必要的库)时,问题就出现了。由于以下错误,应用程序终止失败:

线程“main”java.lang.NoClassDefFoundError中出现异常: org/apache/mesos/Scheduler位于 java.lang.ClassLoader.defineClass1(本机方法)

据我所知,Mesos有一个问题,我无法理解。如果此信息有帮助,这是EMR群集的信息:

  • AMI版本:2.4.2
  • Hadoop发行版:Amazon 1.0.3
  • Spark版本:0.8.1
  • Scala版本:2.9.3

正如@samthebest在上述评论中指出的,该错误实际上是由于EMR上的Spark版本与我的应用程序不匹配造成的


我从这个错误中学到的是,检查用于执行自定义应用程序的所有库和应用程序是否使用与集群相同的版本是非常重要的。

那么您尝试构建胖jar了吗?但还是不起作用?我怀疑您导入的Spark版本与集群上的版本不同。您要导入哪个版本的Spark?@samthebest我已经检查了Amazon在提供的引导文件,Spark版本似乎是0.5,而我的应用程序是使用1.0版本开发的。我会检查它现在是否有效。哇,0.5,那是石器时代的。上次我检查时,我认为他们在0.8.1(更像青铜时代)上的位置。@samthebest是的,我现在切换到0.8.1版本:P。我再次制作了一个胖罐子,但出现了不同的NoClassDefFoundError,这次是指mesos调度程序。我已经更新了这个问题以适应这个新情况。请包括你拉进去的maven人工制品的所有坐标。提示:不要使用EMR!!我们使用EC2并坚持使用Cloudera软件包为我们的JAR安装spark和Cloudera maven coords。我在设置Spark EMR基础设施时遇到了太多麻烦,所以我切换到Spark Standalone,现在我正在快速运行自己的复杂应用程序。谢谢你的提示!
import scala.Tuple2;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.FlatMapFunction;
import org.apache.spark.api.java.function.Function2;
import org.apache.spark.api.java.function.PairFunction;

import java.util.Arrays;
import java.util.List;

public class SparkApp {
  public static void main(String[] args) throws Exception {

    JavaSparkContext ctx = new JavaSparkContext("local", "JavaWordCount",
        System.getenv("SPARK_HOME"), System.getenv("SPARK_EXAMPLES_JAR"));
    JavaRDD<String> lines = ctx.textFile("c3://murquiabucket/wordcount.txt", 1);

    JavaRDD<String> words = lines.flatMap(new FlatMapFunction<String, String>() {
      public Iterable<String> call(String s) {
        return Arrays.asList(s.split(" "));
      }
    });

    JavaPairRDD<String, Integer> ones = words.map(new PairFunction<String, String, Integer>() {
      public Tuple2<String, Integer> call(String s) {
        return new Tuple2<String, Integer>(s, 1);
      }
    });

    JavaPairRDD<String, Integer> counts = ones.reduceByKey(new Function2<Integer, Integer, Integer>() {
      public Integer call(Integer i1, Integer i2) {
        return i1 + i2;
      }
    });

    List<Tuple2<String, Integer>> output = counts.collect();
    for (Tuple2 tuple : output) {
      System.out.println(tuple._1 + ": " + tuple._2);
    }
    System.exit(0);
  }
}