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