Introducción

MapReduce es un modelo de programación y una plataforma de procesamiento de datos que permite el procesamiento de grandes conjuntos de datos de manera distribuida. Fue desarrollado por Google y es una de las piedras angulares del ecosistema Hadoop. Este modelo divide el procesamiento en dos fases principales: Map y Reduce.

Objetivos de Aprendizaje

Al final de esta sección, deberías ser capaz de:

  1. Comprender el flujo de trabajo de MapReduce.
  2. Identificar las fases de Map y Reduce.
  3. Escribir y ejecutar un programa básico de MapReduce.
  4. Conocer los componentes clave del marco de trabajo MapReduce.

Conceptos Clave

  1. Fases de MapReduce

Fase de Map

  • Entrada: La entrada se divide en fragmentos y se asigna a diferentes nodos en el clúster.
  • Procesamiento: Cada nodo procesa su fragmento de datos y genera pares clave-valor intermedios.
  • Salida: Los pares clave-valor intermedios se agrupan por clave.

Fase de Reduce

  • Entrada: Los pares clave-valor intermedios agrupados se pasan a la fase de Reduce.
  • Procesamiento: Cada nodo Reduce procesa los pares clave-valor y genera la salida final.
  • Salida: La salida final se escribe en el sistema de archivos distribuido.

  1. Componentes Clave

  • JobTracker: Coordina los trabajos de MapReduce y asigna tareas a los nodos.
  • TaskTracker: Ejecuta las tareas asignadas por el JobTracker.
  • InputFormat: Define cómo se dividen los datos de entrada.
  • OutputFormat: Define cómo se escriben los datos de salida.

Ejemplo Práctico

Vamos a escribir un programa básico de MapReduce en Java que cuenta la frecuencia de palabras en un conjunto de documentos.

Código de Ejemplo

Clase Mapper

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;

public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
    private final static IntWritable one = new IntWritable(1);
    private Text word = new Text();

    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        String[] words = value.toString().split("\\s+");
        for (String str : words) {
            word.set(str);
            context.write(word, one);
        }
    }
}

Clase Reducer

import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
        int sum = 0;
        for (IntWritable val : values) {
            sum += val.get();
        }
        context.write(key, new IntWritable(sum));
    }
}

Clase Driver

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class WordCount {
    public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf, "word count");
        job.setJarByClass(WordCount.class);
        job.setMapperClass(WordCountMapper.class);
        job.setCombinerClass(WordCountReducer.class);
        job.setReducerClass(WordCountReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);
        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }
}

Explicación del Código

  1. WordCountMapper: Esta clase extiende Mapper y sobrescribe el método map. Divide cada línea de texto en palabras y emite cada palabra con un valor de 1.

  2. WordCountReducer: Esta clase extiende Reducer y sobrescribe el método reduce. Suma los valores para cada palabra y emite la palabra con su frecuencia total.

  3. WordCount: Esta es la clase principal que configura el trabajo de MapReduce. Define las clases Mapper y Reducer, y especifica los formatos de entrada y salida.

Ejercicio Práctico

Ejercicio 1: Contar la Frecuencia de Palabras

Objetivo: Modificar el programa de ejemplo para que ignore las palabras comunes (stop words) como "the", "is", "in", etc.

Pistas:

  • Usa un conjunto (Set) para almacenar las palabras comunes.
  • Filtra estas palabras en el método map antes de emitir los pares clave-valor.

Solución

Clase Mapper Modificada

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
    private final static IntWritable one = new IntWritable(1);
    private Text word = new Text();
    private Set<String> stopWords;

    @Override
    protected void setup(Context context) throws IOException, InterruptedException {
        stopWords = new HashSet<>();
        stopWords.add("the");
        stopWords.add("is");
        stopWords.add("in");
        // Añadir más palabras comunes según sea necesario
    }

    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        String[] words = value.toString().split("\\s+");
        for (String str : words) {
            if (!stopWords.contains(str.toLowerCase())) {
                word.set(str);
                context.write(word, one);
            }
        }
    }
}

Conclusión

En esta sección, hemos cubierto los conceptos básicos del marco de trabajo MapReduce, incluyendo sus fases y componentes clave. También hemos escrito y ejecutado un programa básico de MapReduce para contar la frecuencia de palabras en un conjunto de documentos. A través de un ejercicio práctico, hemos aprendido a modificar el programa para ignorar palabras comunes.

En el próximo módulo, profundizaremos en las técnicas de optimización de MapReduce para mejorar el rendimiento y la eficiencia de nuestros trabajos de procesamiento de datos.

© Copyright 2024. Todos los derechos reservados