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:
- Comprender el flujo de trabajo de MapReduce.
 - Identificar las fases de Map y Reduce.
 - Escribir y ejecutar un programa básico de MapReduce.
 - Conocer los componentes clave del marco de trabajo MapReduce.
 
Conceptos Clave
- 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.
 
- 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
- 
WordCountMapper: Esta clase extiende
Mappery sobrescribe el métodomap. Divide cada línea de texto en palabras y emite cada palabra con un valor de1. - 
WordCountReducer: Esta clase extiende
Reducery sobrescribe el métodoreduce. Suma los valores para cada palabra y emite la palabra con su frecuencia total. - 
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 
mapantes 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.
Curso de Hadoop
Módulo 1: Introducción a Hadoop
- ¿Qué es Hadoop?
 - Visión General del Ecosistema Hadoop
 - Hadoop vs Bases de Datos Tradicionales
 - Configuración del Entorno Hadoop
 
Módulo 2: Arquitectura de Hadoop
- Componentes Principales de Hadoop
 - HDFS (Sistema de Archivos Distribuido de Hadoop)
 - Marco de Trabajo MapReduce
 - YARN (Yet Another Resource Negotiator)
 
Módulo 3: HDFS (Sistema de Archivos Distribuido de Hadoop)
Módulo 4: Programación MapReduce
- Introducción a MapReduce
 - Flujo de Trabajo de un Job MapReduce
 - Escribiendo un Programa MapReduce
 - Técnicas de Optimización de MapReduce
 
Módulo 5: Herramientas del Ecosistema Hadoop
Módulo 6: Conceptos Avanzados de Hadoop
- Seguridad en Hadoop
 - Gestión de Clústeres Hadoop
 - Ajuste de Rendimiento de Hadoop
 - Serialización de Datos en Hadoop
 
Módulo 7: Aplicaciones del Mundo Real y Estudios de Caso
- Hadoop en Almacenamiento de Datos
 - Hadoop en Aprendizaje Automático
 - Hadoop en Procesamiento de Datos en Tiempo Real
 - Estudios de Caso de Implementaciones de Hadoop
 
