it-swarm.com.de

Aufruf eines mapreduce-Jobs aus einem einfachen Java-Programm

Ich habe versucht, einen mapreduce-Auftrag aus einem einfachen Java-Programm im selben Paket aufzurufen. Ich habe versucht, die mapreduce-JAR-Datei in meinem Java-Programm zu referenzieren und sie mit der runJar(String args[])-Methode aufzurufen, indem ich auch die Eingabe- und Ausgabepfade für mapreduce übergebe Job .. Aber das Programm dint Arbeit .. 


Wie führe ich ein solches Programm aus, bei dem ich nur Eingabe, Ausgabe und JAR-Pfad zu seiner Hauptmethode verwende? Ist es möglich, einen mapreduce-Job (jar) dadurch auszuführen? Ich möchte dies tun, weil ich mehrere mapreduce-Jobs nacheinander ausführen möchte, wobei mein Java-Programm vl jeden solchen Job durch Verweisen auf seine JAR-Datei aufruft. Wenn dies möglich ist, kann ich auch ein einfaches Servlet verwenden, um einen solchen Aufruf durchzuführen und verweisen Sie auf die Ausgabedateien für den Graphenzweck.


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author root
 */
import org.Apache.hadoop.util.RunJar;
import Java.util.*;

public class callOther {

    public static void main(String args[])throws Throwable
    {

        ArrayList arg=new ArrayList();

        String output="/root/Desktp/output";

        arg.add("/root/NetBeansProjects/wordTool/dist/wordTool.jar");

        arg.add("/root/Desktop/input");
        arg.add(output);

        RunJar.main((String[])arg.toArray(new String[0]));

    }
}
21
Ravi Trivedi

Oh, bitte nicht mit runJar, die Java API ist sehr gut.

Sehen Sie, wie Sie einen Job mit normalem Code starten können:

// create a configuration
Configuration conf = new Configuration();
// create a new job based on the configuration
Job job = new Job(conf);
// here you have to put your mapper class
job.setMapperClass(Mapper.class);
// here you have to put your reducer class
job.setReducerClass(Reducer.class);
// here you have to set the jar which is containing your 
// map/reduce class, so you can use the mapper class
job.setJarByClass(Mapper.class);
// key/value of your reducer output
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
// this is setting the format of your input, can be TextInputFormat
job.setInputFormatClass(SequenceFileInputFormat.class);
// same with output
job.setOutputFormatClass(TextOutputFormat.class);
// here you can set the path of your input
SequenceFileInputFormat.addInputPath(job, new Path("files/toMap/"));
// this deletes possible output paths to prevent job failures
FileSystem fs = FileSystem.get(conf);
Path out = new Path("files/out/processed/");
fs.delete(out, true);
// finally set the empty out path
TextOutputFormat.setOutputPath(job, out);

// this waits until the job completes and prints debug out to STDOUT or whatever
// has been configured in your log4j properties.
job.waitForCompletion(true);

Wenn Sie einen externen Cluster verwenden, müssen Sie Ihrer Konfiguration die folgenden Informationen hinzufügen:

// this should be like defined in your mapred-site.xml
conf.set("mapred.job.tracker", "jobtracker.com:50001"); 
// like defined in hdfs-site.xml
conf.set("fs.default.name", "hdfs://namenode.com:9000");

Dies sollte kein Problem sein, wenn hadoop-core.jar in Ihrem Anwendungscontainer classpath ..__ ist. Aber ich denke, Sie sollten eine Art Fortschrittsanzeige auf Ihre Webseite setzen, da es einige Minuten dauern kann, um einen hadoop-Job abzuschließen;)

Für YARN (> Hadoop 2)

Für YARN müssen die folgenden Konfigurationen festgelegt werden.

// this should be like defined in your yarn-site.xml
conf.set("yarn.resourcemanager.address", "yarn-manager.com:50001"); 

// framework is now "yarn", should be defined like this in mapred-site.xm
conf.set("mapreduce.framework.name", "yarn");

// like defined in hdfs-site.xml
conf.set("fs.default.name", "hdfs://namenode.com:9000");
31
Thomas Jungblut

MapReduce-Job von der Java-Webanwendung (Servlet) aus aufrufen

Sie können einen MapReduce-Job über die Java-API von einer Webanwendung aus aufrufen. Hier ist ein kleines Beispiel für das Aufrufen eines MapReduce-Jobs von Servlet. Die Schritte sind unten angegeben:

Schritt 1 : Erstellen Sie zunächst eine MapReduce-Treiberservletklasse. Entwickeln Sie auch eine Karte und reduzieren Sie den Service. Hier ein Beispiel-Code-Snippet:

CallJobFromServlet.Java

    public class CallJobFromServlet extends HttpServlet {

    protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {

    Configuration conf = new Configuration();
    // Replace CallJobFromServlet.class name with your servlet class
        Job job = new Job(conf, " CallJobFromServlet.class"); 
        job.setJarByClass(CallJobFromServlet.class);
        job.setJobName("Job Name");
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);
        job.setMapperClass(Map.class); // Replace Map.class name with your Mapper class
        job.setNumReduceTasks(30);
        job.setReducerClass(Reducer.class); //Replace Reduce.class name with your Reducer class
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(Text.class);
        job.setInputFormatClass(TextInputFormat.class);
        job.setOutputFormatClass(TextOutputFormat.class);

        // Job Input path
        FileInputFormat.addInputPath(job, new  
        Path("hdfs://localhost:54310/user/hduser/input/")); 
        // Job Output path
        FileOutputFormat.setOutputPath(job, new 
        Path("hdfs://localhost:54310/user/hduser/output")); 

        job.waitForCompletion(true);
   }
}

Schritt 2 : Platzieren Sie alle zugehörigen JAR-Dateien (hadoop, anwendungsspezifische Jars) -Dateien im lib-Ordner des Webservers (z. B. Tomcat). Dies ist zwingend erforderlich, um auf die Hadoop-Konfigurationen zuzugreifen (hadoop-Ordner "conf" enthält Konfigurations-XML-Dateien, d. H. Core-site.xml, hdfs-site.xml usw.). Kopieren Sie einfach die Jars aus dem hadoop-lib-Ordner in das Webserver (Tomcat) -Lib-Verzeichnis . Die Liste der JAR-Namen lautet wie folgt:

1.  commons-beanutils-1.7.0.jar
2.  commons-beanutils-core-1.8.0.jar
3.  commons-cli-1.2.jar
4.  commons-collections-3.2.1.jar
5.  commons-configuration-1.6.jar
6.  commons-httpclient-3.0.1.jar
7.  commons-io-2.1.jar
8.  commons-lang-2.4.jar
9.  commons-logging-1.1.1.jar
10. hadoop-client-1.0.4.jar
11. hadoop-core-1.0.4.jar
12. jackson-core-asl-1.8.8.jar
13. jackson-mapper-asl-1.8.8.jar
14. jersey-core-1.8.jar

Schritt 3 : Stellen Sie Ihre Webanwendung auf dem Webserver bereit (im Ordner webapps für Tomcat).

Schritt 4 : Erstellen Sie eine JSP-Datei und verknüpfen Sie die Servlet-Klasse (CallJobFromServlet.Java) im Formularaktionsattribut. Hier ein Beispiel-Code-Snippet:

Index.jsp

<form id="trigger_hadoop" name="trigger_hadoop" action="./CallJobFromServlet ">
      <span class="back">Trigger Hadoop Job from Web Page </span> 
      <input type="submit" name="submit" value="Trigger Job" />      
</form>

Eine andere Möglichkeit für Jobs, die bereits in hadoop-Beispielen implementiert wurden, erfordert den Import von Hadoop-Gläsern. Anschließend rufen Sie einfach die statische Hauptfunktion der gewünschten Job-Klasse mit der entsprechenden Zeichenfolge [] der Argumente auf

1
faridasabry

Da Zuordnungen und Reduzierungen auf verschiedenen Maschinen ausgeführt werden, müssen alle referenzierten Klassen und Gläser von Maschine zu Maschine verschoben werden.

Wenn Sie ein Paket jar haben und auf Ihrem Desktop ausführen, ist die Antwort von @ ThomasJungblut in Ordnung. Wenn Sie jedoch in Eclipse laufen, klicken Sie mit der rechten Maustaste auf Ihre Klasse und führen Sie sie aus. Dies funktioniert nicht.

Anstatt:

job.setJarByClass(Mapper.class);

Benutzen:

job.setJar("build/libs/hdfs-javac-1.0.jar");

Zur gleichen Zeit muss das Manifest Ihres Glases die Eigenschaft Main-Class enthalten, die Ihre Hauptklasse ist.

Für gradle Benutzer können diese Zeilen in build.gradle eingefügt werden:

jar {
manifest {
    attributes("Main-Class": mainClassName)
}}
1
Jiang Libo

Das kannst du so machen

public class Test {

    public static void main(String[] args) throws Exception {
        int res = ToolRunner.run(new Configuration(), new YourJob(), args);
        System.exit(res);

    }
0
techlearner

Ich kann mir nicht viele Möglichkeiten vorstellen, wie Sie dies tun können, ohne die hadoop-Core-Bibliothek zu involvieren (oder wie @ThomasJungblut gesagt hat, warum Sie dies möchten).

Wenn Sie dies jedoch unbedingt tun müssen, können Sie einen Oozie-Server mit einem Workflow für Ihren Job einrichten und dann die Oozie-Webservice-Schnittstelle verwenden, um den Workflow an Hadoop zu übermitteln.

Auch dies scheint eine Menge Arbeit für etwas zu sein, das einfach mit der Antwort von Thomas gelöst werden könnte (schließen Sie das Hadoop-Core-Glas ein und verwenden Sie sein Code-Snippet).

0
Chris White