Chiamare un lavoro mapreduce da un semplice programma java

Ho provato a chiamare un lavoro mapreduce da un semplice programma java nello stesso pacchetto. Ho provato a riferire il file jar di mapreduce nel mio programma java e chiamarlo usando il runJar(String args[]) passando anche l’input e i percorsi di output per il lavoro mapreduce .. Ma il programma dint funziona ..


Come eseguo un programma del genere in cui utilizzo solo il pass input, output e jar path per il suo metodo principale ?? È ansible eseguire un lavoro mapreduce (jar) attraverso di esso ?? Voglio farlo perché voglio eseguire più lavori di mapreduce uno dopo l’altro dove il mio programma java vl chiama ciascuno di questi lavori facendo riferimento al suo file jar. Se ciò è ansible, potrei anche usare un semplice servlet per fare tali chiamate e fare riferimento ai suoi file di output per lo scopo del grafico ..


 /* * 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])); } } 

Oh per favore non farlo con runJar , l’API Java è molto buona.

Guarda come puoi iniziare un lavoro dal codice normale:

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

Se si utilizza un cluster esterno, è necessario inserire le seguenti informazioni sulla configurazione tramite:

 // 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"); 

Questo dovrebbe essere un problema quando hadoop-core.jar trova nel classpath dei contenitori dell’applicazione. Ma penso che dovresti mettere un qualche tipo di indicatore di progresso per la tua pagina web, perché potrebbero essere necessari alcuni minuti per completare un lavoro Hadoop;)

Per YARN (> Hadoop 2)

Per YARN, è necessario impostare le seguenti configurazioni.

 // 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"); 

Chiamare il lavoro MapReduce dall’applicazione web java (Servlet)

È ansible chiamare un lavoro MapReduce dall’applicazione Web utilizzando l’API Java. Ecco un piccolo esempio di chiamata a un lavoro MapReduce dal servlet. I passaggi sono indicati di seguito:

Passo 1 : Inizialmente creare una class servlet del driver MapReduce. Sviluppa anche la mappa e riduci il servizio. Ecco un esempio di snippet di codice:

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

Passaggio 2 : posizionare tutti i file jar (hadoop, application specific jars) relativi all’interno della cartella lib del server Web (ad es. Tomcat). Questo è obbligatorio per accedere alle configurazioni Hadoop (la cartella hadoop ‘conf’ ha i file xml di configurazione ie core-site.xml, hdfs-site.xml ecc.). Basta copiare i jar dalla cartella hadoop lib alla directory web server (tomcat) lib. L’elenco dei nomi jar è il seguente:

 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 

Passaggio 3 : distribuisci la tua applicazione web nel server web (nella cartella “webapps” per Tomcat).

Passaggio 4 : creare un file jsp e colbind la class servlet (CallJobFromServlet.java) nell’attributo action form. Ecco un esempio di snippet di codice:

index.jsp

 
Trigger Hadoop Job from Web Page

Un altro modo per i lavori già implementati negli esempi hadoop e richiede anche che i vasi hadoop siano importati .. quindi chiama semplicemente la funzione statica principale del lavoro desiderato Class con la stringa appropriata [] degli argomenti

Poiché mappare e ridurre l’esecuzione su macchine diverse, tutte le classi e i barattoli di riferimento devono passare da una macchina all’altra.

Se si dispone di un pacchetto jar e si esegue sul desktop, la risposta di @JasJungblut è OK. Ma se corri in Eclipse, fai clic con il tasto destro del mouse sulla tua class ed esegui, non funziona.

Invece di:

 job.setJarByClass(Mapper.class); 

Uso:

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

Allo stesso tempo, il manifest del tuo jar deve includere la proprietà Main-Class, che è la tua class principale.

Per gli utenti gradle, è ansible inserire queste righe in build.gradle:

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

Non riesco a pensare a molti modi in cui puoi farlo senza coinvolgere la libreria hadoop-core (o in effetti come @ThomasJungblut ha detto, perché vorresti farlo).

Ma se è assolutamente necessario, è ansible configurare un server Oozie con un stream di lavoro per il proprio lavoro, quindi utilizzare l’interfaccia webservice Oozie per inviare il stream di lavoro a Hadoop.

Di nuovo, questo sembra un sacco di lavoro per qualcosa che potrebbe essere risolto usando la risposta di Thomas (includi il jar hadoop-core e usa il suo frammento di codice)

Puoi fare in questo modo

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