GenericOptionsParser es quien interpreta esas opciones de línea de comandos de Hadoop.
Normalmente no se usa esta clase, sino que se usa ToolRunner que la utiliza internamente y se suele usar en el Driver de un programa MapReduce
Así que si en algún momento queremos pasar opciones de configuración a través de la línea de comandos, en nuestro programa deberemos utilizar ToolRunner e invocando al método ToolRunner.run().
Para pasar opciones de configuración a través de línea de comando se usaría a través de la opción:
-D propiedad=valor
Supongamos que lanzamos la ejecución de un programa MapReduce a través de la línea de comandos de esta forma:
hadoop jar WordCount.jar WordCountDriver -D mapreduce.job.reduces=5 -D mapreduce.job.maps=10 directorioInput directorioOutput
Si no usáramos el ToolRunner tendríamos que controlar las propiedades introducidas haciendo algo parecido a esto:
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
...
conf.set("prop1",args[0]);
conf.set("prop2", args[1]);
...
Job job = new Job(conf);
...
FileInputFormat.setInputPaths(job, new Path(args[2]));
FileOutputFormat.setOutputPath(job, new Path(args[3]));
...
}
Mientras que si utilizamos el ToolRunner, la función run se encarga de parsear por si sólo los argumentos de configuración que hayamos introducido, siempre y cuando hayamos puesto -D delante de la propiedad.
Para desarrollar a través del ToolRunner la clase debe extender de Configured e implementar Tools. Resultando de la forma:
public class WordCountDriver extends Configured implements Tool{
public int run(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = new Job(conf);
...
FileInputFormat.setInputPaths(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
...
}
public static void main(String[] args) throws Exception {
int exitCode = ToolRunner.run(new Configuration(),
new WordCountDriver(), args);
System.exit(exitCode);
}
}
Si os preguntáis cuál es la diferencia y las ventajas entre usar ToolRunner o llamar directamente a la función main con todas las configuraciones, realmente el funcionamiento es el mismo, pero utilizando el ToolRunner es mucho más limpio y no usarlo puede llevarnos a errores como asignar las propiedades después de haber instanciado el Job (que esa propiedad sería nula).
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = new Job(conf);
...
conf.set("prop1",args[0]);
...
// Aquí "prop1 sería nulo en el job
job.getConfiguration().get("prop1");
}
Además de la opción -D que nos permite pasar parámetros a la ejecución, hay que saber que existen otras opciones de línea de comandos que nos permiten:
-files fich1, fich2, ... : Que copia los ficheros indicados del sistema de ficheros local al sistema de ficheros HDFS para utilizarlos en el programa MapReduce.
-libjars jar1, jar2, ... : Que copia las librerías jar especificadas del sistema de ficheros local a HDFS y lo añade al Classpath de la tarea MapReduce (muy útil para añadir dependencias Jar de los Job).
-archives archive1, archive2, ... : Que copia los archivos del sistema de ficheros local a HDFS y poniéndolos a disposición de los programas MapReduce.