java - tutorial - mapreduce mongodb
Llamar a un trabajo mapreduce desde un simple programa java (6)
He estado tratando de llamar a un trabajo mapreduce de un programa Java simple en el mismo paquete. Intenté referir el archivo mapreduce jar a mi programa java y llamarlo usando el runJar(String args[])
al pasar también la entrada y rutas de salida para el trabajo mapreduce .. Pero el programa dint work ...
¿Cómo ejecuto un programa de este tipo en el que solo uso la entrada de paso, la salida y la ruta de acceso de jar a su método principal? ¿Es posible ejecutar un trabajo mapreduce (jar) a través de él? Quiero hacer esto porque quiero ejecutar varios trabajos de mapreduce uno tras otro, donde mi programa java llama a cada uno de esos trabajos remitiendo su archivo jar. Si esto es posible, también podría usar un servlet simple para hacer tales llamadas. y refiere sus archivos de salida para el propósito 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]));
}
}
Debido a que el mapa y la reducción se ejecutan en máquinas diferentes, todas las clases y jarras a las que se hace referencia deben moverse de una máquina a otra.
Si tiene el paquete jar y se ejecuta en su escritorio, la respuesta de @ ThomasJungblut es correcta. Pero si ejecuta en Eclipse, haga clic derecho en su clase y corra, no funciona.
En lugar de:
job.setJarByClass(Mapper.class);
Utilizar:
job.setJar("build/libs/hdfs-javac-1.0.jar");
Al mismo tiempo, el manifiesto de su jar debe incluir la propiedad de clase principal, que es su clase principal.
Para los usuarios de gradle, pueden poner estas líneas en build.gradle:
jar {
manifest {
attributes("Main-Class": mainClassName)
}}
No puedo pensar en muchas maneras en que pueda hacer esto sin involucrar a la biblioteca de hadoop-core (o de hecho, como @ThomasJungblut dijo, por qué querría hacerlo).
Pero si es absolutamente necesario, puede configurar un servidor Oozie con un flujo de trabajo para su trabajo, y luego usar la interfaz del servicio web Oozie para enviar el flujo de trabajo a Hadoop.
- http://yahoo.github.com/oozie/
- http://yahoo.github.com/oozie/releases/2.3.0/WorkflowFunctionalSpec.html#a11.3.1_Job_Submission
Nuevamente, esto parece mucho trabajo para algo que solo podría resolverse usando la respuesta de Thomas (incluya el jar de hadoop-core y use su fragmento de código)
Oh, por favor, no lo hagas con runJar
, la API de Java es muy buena.
Vea cómo puede comenzar un trabajo desde el código normal:
// 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);
Si está utilizando un clúster externo, debe ingresar las siguientes informaciones en su configuración a través de:
// 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");
Esto no debería ser un problema cuando hadoop-core.jar
está en su classpath de contenedores de aplicaciones. Pero creo que debe poner algún tipo de indicador de progreso en su página web, ya que puede llevar de minutos a horas completar un trabajo de hadoop;)
Por HILO (> Hadoop 2)
Para YARN, se deben configurar las siguientes configuraciones.
// 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");
Otra forma de trabajos ya implementados en los ejemplos de hadoop y también requiere importar hadoop jar. Luego, simplemente llame a la función principal estática de la clase de trabajo deseada con la cadena apropiada [] de argumentos.
Puedes hacerlo de esta manera
public class Test {
public static void main(String[] args) throws Exception {
int res = ToolRunner.run(new Configuration(), new YourJob(), args);
System.exit(res);
}
Llamar al trabajo de MapReduce desde la aplicación web java (Servlet)
Puede llamar a un trabajo de MapReduce desde una aplicación web utilizando la API de Java. Aquí hay un pequeño ejemplo de llamar a un trabajo de MapReduce desde servlet. Los pasos se dan a continuación:
Paso 1 : Primero crea una clase de servlet del controlador MapReduce. También desarrolle mapas y reduzca el servicio. Aquí va un fragmento de código de muestra:
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);
}
}
Paso 2 : Coloque todos los archivos jar relacionados (hadoop, jar específicos de la aplicación) dentro de la carpeta lib del servidor web (por ejemplo, Tomcat). Esto es obligatorio para acceder a las configuraciones de Hadoop (la carpeta ''conf'' de hadoop tiene archivos xml de configuración, es decir, core-site.xml, hdfs-site.xml, etc.). Simplemente copie los archivos jar de la carpeta hadoop lib en el directorio web server (tomcat) lib. La lista de nombres jar es la siguiente:
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
Paso 3 : Implemente su aplicación web en el servidor web (en la carpeta ''webapps'' de Tomcat).
Paso 4 : cree un archivo jsp y vincule la clase de servlet (CallJobFromServlet.java) en el atributo de acción formulario. Aquí va un fragmento de código de muestra:
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>