import java.io.IOException; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Mapper; // Esta clase tiene que extender de la clase Mapper. // Espera 4 tipos de datos: los 2 primeros definen // los tipos del key/value de entrada y los 2 últimos // definen los tipos del key/value de salida. public class WordCountMapper extends Mapper <LongWritable, Text, Text, IntWritable> { // Una buena práctica es la reutilización de objetos. // Cuando necesitamos utilizar constantes, crear una // variable estática fuera del map. // De esta forma, cada vez que el método map se llama, // no se creará una nueva instancia de ese tipo. private final static IntWritable cuenta = new IntWritable(1); private Text palabra = new Text(); // La función que obligatoriamente tiene que // implementarse en el Mapper es la map, que va // a recibir como parámetros: primero el tipo de // la key, luego el tipo del value y finalmente un // objeto Context que se usará para escribir los // datos intermedios public void map(LongWritable key, Text values, Context context) throws IOException, InterruptedException{ // En el objeto "values" estamos recibiendo cada // línea del fichero que estamos leyendo. Primero // tenemos que pasarlo a String para poder // operar con él String linea = values.toString(); // Cada línea va a contener palabras separadas por // "un separador", separador que se considera como // una expresión regular y a partir del cual dividimos // la línea. Vamos recorriendo elemento a elemento. for(String word : linea.split(" ")){ if (word.length() > 0){ // Le damos el valor a nuestro objeto creado para la // reutilización (claramente, a 'palabra', ya que // 'cuenta' es una constante final static). // Con el write escribimos los datos intermedios, que // son como key la palabra y como valor un 1. palabra.set(word); context.write(palabra, cuenta); } } } }
Ahora os muestro el código con la old API que vemos que también tiene algunas diferencias. Además, aprovecho para que os fijéis en la parte output.collect, ahí se está creando cada vez una nueva instancia al objeto IntWritable y mostrar que es bastante útil intentar reaprovechar los objetos:
import java.io.IOException; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapred.MapReduceBase; import org.apache.hadoop.mapred.Mapper; import org.apache.hadoop.mapred.OutputCollector; import org.apache.hadoop.mapred.Reporter; public class WordCountMapper extends MapReduceBase implements Mapper <LongWritable, Text, Text, IntWritable> { public void map(LongWritable key, Text value,
OutputCollector<Text, IntWritable> output, Reporter reporter)
throws IOException { String s = value.toString(); for (String word : s.split("\\W+")) { if (word.length() > 0) { output.collect(new Text(word), new IntWritable(1)); } } } }
Las diferencias principales que observamos son:
- En la new API la clase sólo extiende de Mapper, mientras que en la old API necesita extender de MapReduceBase e implementar Mapper.
- La new API recibe 3 atributos: los 2 tipos del par key/value y el context. La old API recibía 4, los 2 tipos de la key/value, un OutputCollector que es donde se escribían los datos intermedios y un objeto Reporter que servía para devolver cierta información al Driver. En la new API este paso de información se puede hacer con el Context.
Ver también:
Continuar con:
Introducción al desarrollo en Java (Parte III): El Reducer (Ejemplo Word Count)
Introducción al desarrollo en Java (Parte IV): El Driver (Ejemplo Word Count)
Introducción al desarrollo en Java (Parte V): Métodos setup() y cleanup()
Introducción al desarrollo en Java (Parte III): El Reducer (Ejemplo Word Count)
Introducción al desarrollo en Java (Parte IV): El Driver (Ejemplo Word Count)
Introducción al desarrollo en Java (Parte V): Métodos setup() y cleanup()
No hay comentarios:
Publicar un comentario
Gracias por dejar vuestras sugerencias, dudas, críticas o comentarios en general