Исключение, когда сервлет пытается запустить Hadoop 2.2.0 MapReduce Job

РЕШЕНО (решение в комментариях)

Я использую Hadoop 2.2.0 (в псевдораспределенном режиме) на Ubuntu 13.10 и Eclipse Kepler v4.3 для разработки своей программы Hadoop и Динамического веб-проекта (без Maven ).

Мой проект jar Hadoop под названием «WorkTest.jar» работает правильно, когда я запускаю задание из командной строки с помощью: «Hadoop jar WorkTest.jar» и правильно вижу ход работы на терминале.

Проект Hadoop содержит четыре элемента:

  • DriverJob.java (класс, который настраивает и запускает задание)
  • Mapper.java
  • Combiner.java
  • Редуктор.java

Теперь я написал новый динамический веб-проект с ServletTest.java, в котором я ввел код класса DriverJob, а другой класс (Mapper.java, Combiner.java, Reducer.java) помещен в тот же пакет, что и сервлет (основной пакет). Папка WebContent/lib содержит все необходимые зависимости jar для Hadoop.

Я успешно развернул свое приложение на сервере WildFly 8 с Eclipse, но когда я пытаюсь запустить задание mapreduce (конфигурация задания выполняется успешно, и мне удалось удалить и записать папку в HDFS), он продолжает давать сбой со следующим исключением, видимым из Файл журнала задания Hadoop:

FATAL [IPC Server handler 5 on 46834] org.apache.hadoop.mapred.TaskAttemptListenerImpl: Task: attempt_1396015900746_0023_m_000002_0 - exited : java.lang.RuntimeException: java.lang.ClassNotFoundException: Class Mapper not found
    at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:1720)
    at org.apache.hadoop.mapreduce.task.JobContextImpl.getMapperClass(JobContextImpl.java:186)
    at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:721)
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:339)
    at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:162)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:415)
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1491)
    at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:157)
Caused by: java.lang.ClassNotFoundException: Class Mapper not found
    at org.apache.hadoop.conf.Configuration.getClassByName(Configuration.java:1626)
    at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:1718)
    ... 8 more

и из файла журнала WildFly:

WARN  [org.apache.hadoop.mapreduce.JobSubmitter] Hadoop command-line option parsing not performed. Implement the Tool interface and execute your application with ToolRunner to remedy this.
WARN  [org.apache.hadoop.mapreduce.JobSubmitter] No job jar file set.  User classes may not be found. See Job or Job#setJar(String).

Но папка WEB-INF/classes/deploy на WildFly, содержащая Mapper.class, Combiner.class и Reducer.class.

Я также пытался ввести код класса Mapper, Combiner и Reducer внутри сервлета, но не работает с той же ошибкой...

Что я делаю неправильно?


person Andrea    schedule 31.03.2014    source источник


Ответы (1)


Я считаю, что вам нужно иметь файлы .class в архиве (jar), который можно распространять на узлы в кластере.

WARN  [org.apache.hadoop.mapreduce.JobSubmitter] No job jar file set.  User classes may not be found. See Job or Job#setJar(String).

Эта ошибка является ключевой. Как правило, вы должны использовать job.setJarByClass(DriverJob.class), чтобы сообщить клиенту mapreduce, в каком файле jar есть классы Mapper/Reducer. У вас нет банки, и поэтому этот метод распределения правильных классов разваливается.

person Mike Park    schedule 31.03.2014
comment
Спасибо за ответ. Я изменил свой подход: я удалил код DriverJob из своего ServletTest и поместил jar-файл Hadoop (WorkTest.jar) в папку WEB-INF/lib. В моем DriverJob.java я установил: job.setJarByClass(jobexecutor.DriverJob.class); job.setMapperClass(jobexecutor.Mapper.class); job.setCombinerClass(jobexecutor.Combiner.class); job.setReducerClass(jobexecutor.Reducer.class); Теперь я вызываю только метод DriverJob String output = jobexecutor.DriverJob.run(String inputData) из сервлета; но когда я пытаюсь запустить задание mapreduce, он продолжает терпеть неудачу с тем же исключением... - person Andrea; 02.04.2014
comment
Возможно, я нашел причину проблемы: если внутри моего класса DriverJob я запускаю метод job.getJar();, это возвращает мне значение null! Почему? - person Andrea; 02.04.2014
comment
И классы картографа/редуктора находятся в этом WorkTest.jar? - person Mike Park; 02.04.2014
comment
Кроме того, убедитесь, что в вашем пути к классам нет устаревших экземпляров этого файла класса. - person Mike Park; 02.04.2014
comment
Да, классы преобразователя/редуктора находятся в WorkTest.jar. Мне удалось решить проблему, используя config.set("mapreduce.job.jar", "full_path_of_my_jobexecutor.jar_in_my_deploy_folder_on_wildfly"); в файле DriverJob.java. Проблема заключалась в том, что метод job.setJarByClass(jobexecutor.DriverJob.class) не смог найти пакет, в котором он содержится... Я принудительно объявил объявление, и ошибка исчезла! - person Andrea; 03.04.2014