2012-06-27 24 views
7

He escrito un programa mapreduce en Java, que puedo enviar a un clúster remoto que se ejecuta en modo distribuido. Actualmente, enviar la tarea mediante los pasos siguientes:Iniciar un trabajo de reducción de mapas de eclipse

  1. exportación el empleo mapreuce como un frasco (por ejemplo, myMRjob.jar)
  2. enviar la tarea al clúster remoto usando el siguiente comando shell: hadoop jar myMRjob.jar

Me gustaría enviar el trabajo directamente desde Eclipse cuando intento ejecutar el programa. ¿Cómo puedo hacer esto?

actualmente estoy usando CDH3, y una versión abreviada de mi conf es:

conf.set("hbase.zookeeper.quorum", getZookeeperServers()); 
conf.set("fs.default.name","hdfs://namenode/"); 
conf.set("mapred.job.tracker", "jobtracker:jtPort"); 
Job job = new Job(conf, "COUNT ROWS"); 
job.setJarByClass(CountRows.class); 

// Set up Mapper 
TableMapReduceUtil.initTableMapperJob(inputTable, scan, 
    CountRows.MyMapper.class, ImmutableBytesWritable.class, 
    ImmutableBytesWritable.class, job); 

// Set up Reducer 
job.setReducerClass(CountRows.MyReducer.class); 
job.setNumReduceTasks(16); 

// Setup Overall Output 
job.setOutputFormatClass(MultiTableOutputFormat.class); 

job.submit(); 

Cuando ejecuto esto directamente desde Eclipse, el trabajo se pone en marcha, pero Hadoop no puedo encontrar los aplicadores/reductores. Obtengo los siguientes errores:

12/06/27 23:23:29 INFO mapred.JobClient: map 0% reduce 0% 
12/06/27 23:23:37 INFO mapred.JobClient: Task Id : attempt_201206152147_0645_m_000000_0, Status : FAILED 
java.lang.RuntimeException: java.lang.ClassNotFoundException: com.mypkg.mapreduce.CountRows$MyMapper 
    at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:996) 
    at org.apache.hadoop.mapreduce.JobContext.getMapperClass(JobContext.java:212) 
    at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:602) 
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:323) 
    at org.apache.hadoop.mapred.Child$4.run(Child.java:270) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at javax.security.auth.Subject.doAs(Subject.java:396) 
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1127) 
    at org.apache.hadoop.mapred.Child.main(Child.java:264) 
... 

¿Alguien sabe cómo pasar estos errores? Si puedo solucionar esto, puedo integrar más trabajos de MR en mis scripts, ¡lo cual sería increíble!

+0

Tucker - yo era capaz de ejecutar el trabajo Hadoop en independiente, pero no a otros modos de Eclipse. Publiqué la consulta en los foros de Hadoop hace algún tiempo y no hubo ninguna respuesta + ve. Por cierto, Hadoop se ejecuta en el modo independiente sin ningún archivo de configuración (parámetros predeterminados). –

+0

Cuando envía el trabajo desde dentro de Eclipse, ¿las clases del asignador/reductor están en el mismo proyecto, o el contenedor que las contiene en el classpath, y las clases en ningún otro lugar en el cp? –

+0

@ChrisWhite La clase que contiene todo se llama CountRows. Esta clase contiene un método "principal" que establece las configuraciones de trabajo. la clase CountRows también contiene la clase para el asignador y el reductor llamados MyMapper y MyReducer, respectivamente. El trabajo funciona bien como dije cuando lancé el trabajo desde la línea de comandos escribiendo 'hadoop jar CountRows.jar' – Tucker

Respuesta

8

Si está enviando el trabajo hadoop desde dentro del proyecto Eclipse que define las clases para el trabajo, es muy probable que tenga un problema de ruta de clase.

La llamada job.setjarByClass(CountRows.class) encuentra el archivo de clase en la classpath de compilación, y no en el CountRows.jar (que puede o no haberse creado aún, o incluso en la ruta de clases).

Debería poder afirmar que esto es cierto imprimiendo el resultado de job.getJar() después de llamar al job.setjarByClass(..), y si no muestra un archivo jar, entonces encontró la clase de compilación, en lugar de la clase jar'd

+0

Ok, ejecuté "job.setJarByClass (CountRows.class); \t \t System.out.println (" getClass ...: "+ job.getClass());" y el resultado fue simplemente "getClass ...: clase org.apache.hadoop.mapreduce.Job" – Tucker

+0

Bueno, eso no es sorprendente si se considera el tipo de clase de trabajo. Pruebe 'job.getJar()' en lugar de 'job.getClass()' –

+0

Ha, ¡su método correcto-incorrecto! Lo ejecuté ahora, dice que es nulo. ¿Hay alguna manera de hacer que funcione cuando ejecuto el programa a través de eclipse? – Tucker

1

he utilizado este método en el siguiente sitio web para configurar un mapa/Reducir proyecto mío para ejecutar el proyecto con Eclipse (w/o exportación de proyecto como JAR) Configuring Eclipse to run Hadoop Map/Reduce project

Nota: Si decide depuración programa, su clase Mapper y clase Reducer no serán depurables.

Espero que ayude. :)

+1

Debe proporcionar un resumen de la solución, no solo proporcionar un enlace que podría desaparecer – Mark

+1

Usted dijo "Si decide depurar su programa, su clase Mapper y clase Reducer no serán depurables". ¿Por qué es esto y siempre es cierto? – John

2

Lo que funcionó para mí fue exportar un JAR ejecutable (la diferencia entre él y un JAR es que el primero define la clase, que tiene el método principal) y seleccionar la opción "empaquetar bibliotecas requeridas en JAR" (eligiendo la opción "extrayendo ..." lleva a errores duplicados y también tiene que extraer los archivos de clase de los archivos jar, lo que, en última instancia, en mi caso, resultó en la no resolución de la excepción de clase no encontrada).

Después de eso, puede simplemente configurar el recipiente, como fue sugerido por Chris White. Para Windows que se vería así: job.setJar("C:\\\MyJar.jar");

Si se ayuda a nadie, hice una presentación sobre lo que aprendí de creating a MapReduce project and running it in Hadoop 2.2.0 in Windows 7 (in Eclipse Luna)

Cuestiones relacionadas