Introducción
En este tema, exploraremos el paradigma de programación MapReduce y su implementación más conocida, Hadoop. MapReduce es un modelo de programación diseñado para procesar grandes volúmenes de datos de manera distribuida y paralela. Hadoop es un marco de trabajo que permite el procesamiento distribuido de grandes conjuntos de datos utilizando el modelo MapReduce.
Objetivos
- Comprender el paradigma de programación MapReduce.
- Conocer la arquitectura y componentes de Hadoop.
- Aprender a escribir y ejecutar trabajos de MapReduce en Hadoop.
- Realizar ejercicios prácticos para consolidar los conocimientos adquiridos.
Conceptos Básicos de MapReduce
Fases de MapReduce
MapReduce se divide en dos fases principales:
- Map: Esta fase toma un conjunto de datos de entrada y los convierte en pares clave-valor intermedios.
- Reduce: Esta fase toma los pares clave-valor intermedios y los procesa para generar el resultado final.
Ejemplo de MapReduce
Supongamos que queremos contar la frecuencia de palabras en un gran conjunto de documentos. El proceso sería el siguiente:
-
Map:
- Entrada: Un documento de texto.
- Salida: Pares clave-valor donde la clave es una palabra y el valor es 1.
(word1, 1) (word2, 1) (word1, 1) -
Shuffle and Sort:
- Agrupa todas las claves iguales.
(word1, [1, 1]) (word2, [1]) -
Reduce:
- Suma los valores para cada clave.
(word1, 2) (word2, 1)
Arquitectura de Hadoop
Hadoop consta de varios componentes clave:
- Hadoop Distributed File System (HDFS): Sistema de archivos distribuido que almacena datos en bloques distribuidos a través de múltiples nodos.
- MapReduce Engine: Motor que ejecuta trabajos de MapReduce.
- YARN (Yet Another Resource Negotiator): Sistema de gestión de recursos que coordina la ejecución de trabajos.
Componentes de HDFS
- NameNode: Nodo maestro que gestiona la metadata del sistema de archivos.
- DataNode: Nodos esclavos que almacenan los bloques de datos.
Componentes de YARN
- ResourceManager: Nodo maestro que gestiona los recursos del clúster.
- NodeManager: Nodos esclavos que ejecutan contenedores de aplicaciones.
Escribiendo un Trabajo de MapReduce en Hadoop
Ejemplo en Java
A continuación, se presenta un ejemplo de un trabajo de MapReduce en Java para contar palabras:
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.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import java.io.IOException;
import java.util.StringTokenizer;
public class WordCount {
public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString());
while (itr.hasMoreTokens()) {
word.set(itr.nextToken());
context.write(word, one);
}
}
}
public static class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
private IntWritable result = new IntWritable();
public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
result.set(sum);
context.write(key, result);
}
}
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(TokenizerMapper.class);
job.setCombinerClass(IntSumReducer.class);
job.setReducerClass(IntSumReducer.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
- TokenizerMapper: Lee líneas de texto y emite pares clave-valor donde la clave es una palabra y el valor es 1.
- IntSumReducer: Suma los valores para cada clave (palabra) y emite el resultado.
- main: Configura y ejecuta el trabajo de MapReduce.
Ejercicio Práctico
Ejercicio 1: Contar la Frecuencia de Palabras
- Objetivo: Implementar y ejecutar un trabajo de MapReduce para contar la frecuencia de palabras en un conjunto de documentos de texto.
- Instrucciones:
- Configura un clúster de Hadoop (puede ser un clúster local).
- Escribe el código de MapReduce en Java (puedes usar el ejemplo proporcionado).
- Compila y empaqueta el código en un archivo JAR.
- Ejecuta el trabajo de MapReduce en el clúster de Hadoop.
- Verifica los resultados.
Solución
- Configuración del Clúster: Sigue la documentación oficial de Hadoop para configurar un clúster local.
- Código de MapReduce: Usa el ejemplo proporcionado anteriormente.
- Compilación y Ejecución:
javac -classpath `hadoop classpath` -d wordcount_classes WordCount.java jar -cvf wordcount.jar -C wordcount_classes/ . hadoop jar wordcount.jar WordCount /input /output
Conclusión
En este tema, hemos aprendido sobre el paradigma de programación MapReduce y su implementación en Hadoop. Hemos explorado la arquitectura de Hadoop y cómo escribir y ejecutar trabajos de MapReduce. Los ejercicios prácticos proporcionados ayudarán a consolidar los conocimientos adquiridos.
En el próximo tema, exploraremos Spark y la computación en memoria, que ofrece una alternativa más rápida y flexible a MapReduce para ciertos tipos de procesamiento de datos.
Curso de Arquitecturas Distribuidas
Módulo 1: Introducción a los Sistemas Distribuidos
- Conceptos Básicos de Sistemas Distribuidos
- Modelos de Sistemas Distribuidos
- Ventajas y Desafíos de los Sistemas Distribuidos
