2012-06-27 9 views
7

Ich habe ein mapreduce-Programm in Java geschrieben, das ich an einen Remote-Cluster im verteilten Modus senden kann. Derzeit ich den Job mit den folgenden Schritten einreichen:Starten eines mapreduce-Jobs aus der Eclipse

  1. Export des mapreuce Job als Glas (zB myMRjob.jar)
  2. den Auftrag an die Remote-Cluster senden Sie den folgenden Shell-Befehl: hadoop jar myMRjob.jar

Ich möchte den Job direkt von Eclipse einreichen, wenn ich versuche, das Programm auszuführen. Wie kann ich das machen?

Ich bin derzeit CDH3 und eine gekürzte Version meiner conf ist:

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(); 

Als ich das direkt von Eclipse-laufen, wird der Auftrag gestartet, aber Hadoop können nicht die Mapper/Reduzierungen finden. Ich erhalte folgende Fehler:

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) 
... 

Weiß jemand, wie man über diese Fehler hinauskommt? Wenn ich das beheben kann, kann ich mehr MR-Jobs in meine Skripte integrieren, was großartig wäre!

+0

Tucker - konnte ich die Hadoop Job in Stand-alone laufen, aber nicht andere Modi aus Finsternis. Ich habe die Abfrage in den Hadoop-Foren einige Zeit zurück gepostet und es gab keine + ve Antwort. Übrigens läuft Hadoop im Standalone-Modus ohne Konfigurationsdateien (Standardparameter). –

+0

Wenn Sie den Job in Eclipse übergeben, befinden sich die Mapper-/Reducer-Klassen im selben Projekt oder ist das Jar, das sie enthält, im Klassenpfad und die Klassen selbst nirgendwo sonst auf dem CP? –

+0

@ChrisWhite Die Klasse, die alles enthält, heißt CountRows. Diese Klasse enthält eine Hauptmethode, die die Jobkonfigurationen festlegt. Die Klasse CountRows enthält auch die Klasse für den Mapper und Reducer namens MyMapper bzw. MyReducer. Der Job funktioniert gut, wie ich sagte, wenn ich den Job von der comandline durch das Schreiben 'hadoop jar CountRows.jar' – Tucker

Antwort

8

Wenn Sie den Hadoop-Job aus dem Eclipse-Projekt senden, in dem die Klassen für den Job definiert sind, liegt wahrscheinlich ein Klassenpfadproblem vor.

Der Aufruf job.setjarByClass(CountRows.class) findet die Klassendatei auf dem Buildklassenpfad und nicht in der CountRows.jar (die möglicherweise noch nicht oder sogar auf dem Klassenpfad erstellt wurde).

Sie sollten in der Lage sein, dies zu bestätigen, indem Sie das Ergebnis job.getJar() ausdrucken, nachdem Sie job.setjarByClass(..) aufgerufen haben, und wenn es keinen JAR-Dateipfad anzeigt, wird die build-Klasse statt der jar'd-Klasse gefunden

+0

Ok, ich rannte "job.setJarByClass (CountRows.class); \t \t System.out.println (" getClass ...: "+ job.getClass());" und das Ergebnis war einfach "getClass ...: class org.apache.hadoop.mapreduce.Job" – Tucker

+0

Nun, das ist nicht überraschend, wenn man bedenkt, dass man nach dem Klassentyp Job fragt. Versuchen Sie 'job.getJar()' anstelle von 'job.getClass()' –

+0

Ha, Ihre richtige - falsche Methode! Ich habe es jetzt ausgeführt, es sagt seine Null. Gibt es eine Möglichkeit, es zum Laufen zu bringen, wenn ich das Programm durch Eclipse laufen lasse? – Tucker

1

ich habe diese Methode von der folgenden Website verwendet, um eine Map/Reduce Projekt von mir zu konfigurieren, um das Projekt mit Eclipse (w/o Export-Projekt als JAR) Configuring Eclipse to run Hadoop Map/Reduce project

Hinweis auszuführen: Wenn Sie debuggen entscheiden Sie Programm, Ihre Klasse und Reducer Klasse wird nicht Debug-fähig sein.

Ich hoffe, es hilft. :)

+1

Sie sollten eine Zusammenfassung der Lösung nicht nur einen Link zur Verfügung stellen, die weggehen könnte – Mark

+1

Sie sagten: "Wenn Sie entscheiden, Sie zu debuggen, werden Ihre Mapper-Klasse und Reducer-Klasse nicht Debug-fähig sein." Warum ist das und ist es immer wahr? – John

2

Was für mich funktionierte, war das Exportieren eines ausführbaren JAR (der Unterschied zwischen diesem und einem JAR ist, dass der erste die Klasse definiert, die die Hauptmethode hat) und die Option "packaging required libraries in JAR" auswählt Die Option "extracting ..." führt zu doppelten Fehlern und muss auch die Klassendateien aus den jars extrahieren, was in meinem Fall dazu führte, dass die Klasse nicht gefunden wurde (Ausnahme).

Danach können Sie einfach das Glas setzen, wie es von Chris White vorgeschlagen wurde. Für Windows würde es so aussehen: job.setJar("C:\\\MyJar.jar");

Wenn es jemand hilft, habe ich eine Präsentation gemacht, was ich von creating a MapReduce project and running it in Hadoop 2.2.0 in Windows 7 (in Eclipse Luna) gelernt

Verwandte Themen