2014-11-12 3 views
0

Я разработал программу уменьшения масштаба, используя Apache Hadoop 1.2.1. Я сделал начальную разработку, используя Eclipse IDE, чтобы имитировать распределенную вычислительную среду hadoop со всеми входными и выходными файлами, поступающими из локальной файловой системы. Эта программа будет выполнена в Eclipse без проблем. Затем я создаю файл JAR с помощью Eclipse, и попытаться запустить это на мой кластер из-одной Hadoop машины и получать сообщения об ошибках:Hadoop mapper class не найден

Вот мой код, чтобы установить и запустить задание Hadoop:

String outputPath = "/output"; 
String hadoopInstructionsPath = args[0]; 

Job job = new Job(); 
job.setJarByClass(Main.class); //setJarByClass is here but not found apparently?!? 
job.setJobName("KLSH"); 

FileInputFormat.addInputPath(job, new Path(hadoopInstructionsPath)); 
FileOutputFormat.setOutputPath(job,new Path(outputPath)); 


job.setMapperClass(KLSHMapper.class); 
job.setReducerClass(KLSHReducer.class); 

job.setOutputKeyClass(Text.class); 
job.setOutputValueClass(Text.class); 

System.exit(job.waitForCompletion(true) ? 0:1); 
boolean success = job.waitForCompletion(true); 
return success ? 0 : 1; 

I затем создайте банку, используя eclipse, с помощью файла File -> Export -> Runnable JAR, чтобы создать файл JAR для запуска в кластере.

Команда, которую я использую для выполнения задания, выглядит следующим образом (KLSH.jar - это имя файла JAR,/hasoopInstruction - это входной параметр args [0] и imageFeature.Main/указывает, где находится основной класс)

./hadoop jar ./KLSH.jar /hadoopInstructions imageFeatures.Main/ 

Это производит следующий вывод:

14/11/12 11:11:48 WARN mapred.JobClient: Use GenericOptionsParser for parsing the arguments. Applications should implement Tool for the same. 
14/11/12 11:11:48 WARN mapred.JobClient: No job jar file set. User classes may not be found. See JobConf(Class) or JobConf#setJar(String). 
14/11/12 11:11:48 INFO input.FileInputFormat: Total input paths to process : 1 
14/11/12 11:11:48 INFO util.NativeCodeLoader: Loaded the native-hadoop library 
14/11/12 11:11:48 WARN snappy.LoadSnappy: Snappy native library not loaded 
14/11/12 11:11:49 INFO mapred.JobClient: Running job: job_201411051030_0022 
14/11/12 11:11:50 INFO mapred.JobClient: map 0% reduce 0% 
14/11/12 11:11:56 INFO mapred.JobClient: Task Id : attempt_201411051030_0022_m_000000_0, Status : FAILED 
java.lang.RuntimeException: java.lang.ClassNotFoundException: imageFeatures.KLSHMapper 
... 

Так это ошибки, потому что он не может найти класс картографа. Существует предупреждение «Нет заданий в файле jar file», но я чувствую, что я указал job.setJarByClass в первом блоке кода, поэтому не знаю, почему эта ошибка возникает ...

I также знать класс KLSHMapper находится в JAR, потому что, если я выполнить следующую команду:

jar tf KLSH.jar 

Я получаю довольно много продукции, но вот часть выхода:

... 
imageFeatures/Main.class 
imageFeatures/Feature.class 
imageFeatures/FileLoader.class 
imageFeatures/KLSHMapper.class 
... 

Так ясно Класс KLSHMapper там ... Я пробовал модифицировать мой путь класса hadoop, чтобы включить путь KLSH.jar, Я попытался скопировать KLSH.jar в DFS и попытаться использовать этот путь вместо пути в локальной файловой системе, и я также попытался выполнить задание с помощью спецификатора -libjars. Независимо от того, что я, кажется, пытаюсь, hadoop, похоже, не может найти мой класс Mapper. Может ли кто-нибудь там указать мне на то, что я делаю неправильно? Я просто не могу сделать переход от моего кода, работающего в Eclipse, чтобы заставить его работать с фактическим кластером Hadoop. Благодаря!

ответ

0

После некоторой дополнительной работы я смог решить свою собственную проблему. В конечном счете, это сводилось к тому, как я создавал файл jar, который затем пытался выполнить на кластере hadoop.

Вместо использования eclipse для создания JAR-файла я использовал Maven из командной строки для создания JAR-файла. В файле pom.xml, вы можете указать главный класс, используя что-то вдоль этих линий:

<plugin> 
<groupId>org.apache.maven.plugins</groupId> 
<artifactId>maven-jar-plugin</artifactId> 
    <configuration> 
     <archive> 
      <manifest> 
       <mainClass>maxTemp.MaxTemperature</mainClass> 
      </manifest> 
     </archive> 
    </configuration> 
</plugin> 

В моем случае, maxTemp был пакет и MaxTemperature был класс, который содержал мой основной метод.Это вызовет файл манифеста, который содержится в JAR, что Maven строит для вас есть следующая строка добавляется к нему:

Main-Class: maxTemp.MaxTemperature 

Теперь, когда вы используете Hadoop для выполнения файла банку, вы больше не придется укажите mainClass, как вы уже делали это в манифесте jar. Без этой строки в манифесте JAR, вам нужно будет выполнять свою работу в кластере, используя следующий синтаксис:

./hadoop jarFile [mainClass] args... 

С линией в файле манифеста, вы можете просто выполнить работу следующим образом:

./hadoop jarFile args... 

Как в стороне и несколько связанный, я столкнулся с некоторыми проблемами, потому что я использовал библиотеку jeigen java для создания некоторой линейной алгебры. Мой кластер не смог найти зависимости, которые я использовал (jeigen.jar), и это вызывало больше ошибок. Я в конечном итоге строить толстую банку, как это было описано на этом сайте:

http://hadoopi.wordpress.com/2014/06/05/hadoop-add-third-party-libraries-to-mapreduce-job/

С некоторыми дополнениями к моему файлу pom.xml, я был в состоянии генерировать maxTemp-банку-с-зависимостей, и Затем кластер смог найти все мои зависимости, потому что они были включены в файл jar. Надеюсь, это поможет спасти кого-то в будущем. Некоторые из этих зависимостей были в моей локальной системе, и Maven не смог их получить. Я был в состоянии указать Maven на них и установить их вручную с помощью следующей команды:

mvn install:install-file -DgroupId=jeigen -DartifactId=jeigen -Dversion=1 -Dpackaging=jar -Dfile=/path/to/the/location/of/Jeigen.jar 

Вот мой pom.xml файл, который генерирует две банки, один с и один без зависимостей включены:

<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>maxTemp</groupId> 
    <artifactId>maxTemp</artifactId> 
    <version>0.0.1</version> 
    <build> 
    <sourceDirectory>src</sourceDirectory> 
    <plugins> 

     <plugin> 
     <artifactId>maven-compiler-plugin</artifactId> 
     <version>3.1</version> 
     <configuration> 
      <source>1.7</source> 
      <target>1.7</target> 
     </configuration> 
     </plugin> 

     <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-jar-plugin</artifactId> 
     <configuration> 
      <archive> 
      <manifest> 
       <mainClass>maxTemp.MaxTemperature</mainClass> 
      </manifest> 
      </archive> 
     </configuration> 
     </plugin> 

     <plugin> 
     <artifactId>maven-assembly-plugin</artifactId> 
      <configuration> 
      <archive> 
       <manifest> 
       <mainClass>maxTemp.MaxTemperature</mainClass> 
       </manifest> 
      </archive> 
      <descriptorRefs> 
       <descriptorRef> 
       jar-with-dependencies 
       </descriptorRef> 
      </descriptorRefs> 
      </configuration> 
     <executions> 
      <execution> 
      <id>make-assembly</id> 
      <phase>package</phase> 
      <goals> 
       <goal>single</goal> 
      </goals> 
      </execution> 
     </executions> 
     </plugin> 

    </plugins> 
    </build> 
    <dependencies> 

    <dependency> 
     <groupId>org.apache.hadoop</groupId> 
     <artifactId>hadoop-client</artifactId> 
     <version>1.2.1</version> 
    </dependency> 

    <dependency> 
     <groupId>org.apache.hadoop</groupId> 
     <artifactId>hadoop-core</artifactId> 
     <version>1.2.1</version> 
    </dependency> 

    <dependency> 
     <groupId>org.apache.hadoop</groupId> 
     <artifactId>hadoop-tools</artifactId> 
     <version>1.2.1</version> 
    </dependency> 

    <dependency> 
     <groupId>jeigen</groupId> 
     <artifactId>jeigen</artifactId> 
     <version>1</version> 
    </dependency> 

    <dependency> 
     <groupId>jna</groupId> 
     <artifactId>jna</artifactId> 
     <version>4.0.0</version> 
    </dependency> 

    </dependencies> 
</project> 
0

У вас есть оператор импорта в файл где-то:

import imageFeatures.KLSHMapper; 

Вам также необходимо включить файл фляги, который содержит imageFeatures.KLSMapper в переменной CLASSPATH среды. Это очень странный и иностранный код, который у вас здесь, поэтому, может быть, я не в курсе ...

+0

Могу я спросить, странно, каким образом? Я основывал свой код на примере кода в книге Hadoop, «Определяющее руководство» (3-е издание). Это мое первое серьезное предприятие, использующее Hadoop для выполнения всего, кроме как подсчета слов. Есть ли лучший способ сделать что-то? – shutch

+0

Я просто не знаком с распределенной вычислительной средой, использующей хаос. Не значит критиковать то, что вы делаете. Я уверен, что ты на правильном пути. Вы просмотрели документацию для класса Job: http://hadoop.apache.org/docs/r2.3.0/api/org/apache/hadoop/mapreduce/Job.html –

+0

Я думаю, все, что я могу сказать наверняка, это что ошибка, которую вы получаете, больше связана с тем, что java не находит файл класса. Должна быть ссылка на физическое местоположение файла jar в CLASSPATH, а затем в Java вам нужно указать, где находится найденный пакет (который обычно выполняется с помощью инструкции import). –

Смежные вопросы