Introducción
Imagina un escenario en el que eres un talentoso ingeniero encargado de manejar datos en un sistema de simulación de batalla espacial. Tu objetivo es optimizar el rendimiento del sistema mediante la implementación de la técnica Hadoop Shuffle Combiner en el proceso MapReduce. Al utilizar el Combiner, pretendes reducir el tráfico de red y mejorar la eficiencia general en el procesamiento de datos durante la simulación.
Escribe el Mapper
En este paso, escribirás la clase Mapper para procesar los datos de entrada y emitir pares clave-valor intermedios.
Abre la terminal y sigue los pasos siguientes para comenzar.
Cambia el usuario a hadoop y luego cambia al directorio principal del usuario hadoop:
su - hadoop
Crea un archivo Java para la clase Mapper:
nano /home/hadoop/SpaceBattleMapper.java
Luego, agrega el siguiente código al archivo SpaceBattleMapper.java:
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Mapper.Context;
import java.io.IOException;
public class SpaceBattleMapper 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 {
// Divide la línea de entrada en palabras
String[] words = value.toString().split("\\s+");
// Emite un par clave-valor para cada palabra
for (String w : words) {
word.set(w);
context.write(word, one);
}
}
}
Consejos: Puedes copiar el código de la caja de prompt de la derecha y pegarlo con Ctrl + Shift + V en el editor nano abierto. Presiona Ctrl + O para guardar el archivo y Enter para confirmar cuando te lo solicite el editor nano. Finalmente, utiliza Ctrl + X para salir del editor.
La clase SpaceBattleMapper extiende la clase Mapper del marco de Hadoop. Se utiliza para procesar datos de entrada en forma de pares clave-valor, donde la clave es un LongWritable que representa el desplazamiento de bytes de la línea en el archivo de entrada, y el valor es un objeto Text que representa la línea de texto.
La clase define dos campos privados:
one: Un objetoIntWritablecon un valor constante de 1. Esto se utiliza como el valor en los pares clave-valor emitidos.word: Un objetoTextutilizado para almacenar cada palabra extraída de la línea de entrada.
El método map se anula para proporcionar la lógica de asignación específica:
- El valor de entrada
Textse convierte en una cadena y se divide en palabras en función de los espacios en blanco. - Para cada palabra en el array, el objeto
wordse establece en esa palabra, y se emite un par clave-valor con la palabra como clave yonecomo valor. Esto se hace utilizando el métodocontext.write.
Esta clase Mapper está diseñada para emitir un par clave-valor para cada palabra en los datos de entrada, con la palabra como clave y el entero 1 como valor. Esta configuración se utiliza comúnmente en aplicaciones de conteo de palabras, donde el objetivo es contar la ocurrencia de cada palabra en un conjunto de datos.
Implementa el Combiner
En este paso, implementarás la clase Combiner para realizar la agregación local antes del mezclado de datos.
Crea un archivo Java para la clase Combiner:
nano /home/hadoop/SpaceBattleCombiner.java
Luego, agrega el siguiente código al archivo SpaceBattleCombiner.java:
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
public class SpaceBattleCombiner extends Reducer<Text, IntWritable, Text, IntWritable> {
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int sum = 0;
// Suma los valores para cada clave
for (IntWritable val : values) {
sum += val.get();
}
// Emite la clave y la suma de sus valores
context.write(key, new IntWritable(sum));
}
}
La clase SpaceBattleCombiner extiende la clase Reducer del marco de Hadoop. Se utiliza como un combiner en el proceso MapReduce para realizar la agregación local de los pares clave-valor intermedios emitidos por el Mapper.
La clase anula el método reduce para proporcionar la lógica específica del combiner:
- El método toma una clave de tipo
Texty un iterable de valores de tipoIntWritablecomo entrada. La clave representa una palabra, y el iterable contiene los conteos de ocurrencias de esa palabra. - El método itera sobre los valores, sumándolos para obtener el recuento total de la palabra.
- Finalmente, el método emite un par clave-valor con la palabra como clave y el recuento total como valor utilizando el método
context.write.
El propósito de SpaceBattleCombiner es realizar la agregación local de los conteos para cada palabra antes de que los datos se mezclen a través de la red hacia el Reducer. Esto reduce la cantidad de datos transferidos entre las fases del Mapper y el Reducer, mejorando la eficiencia del trabajo MapReduce.
Implementa el Reducer
En este paso, implementarás la clase Reducer para realizar la agregación final de los pares clave-valor.
- Crea un archivo Java para la clase Reducer:
nano /home/hadoop/SpaceBattleReducer.java
Luego, agrega el siguiente código al archivo SpaceBattleReducer.java:
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
public class SpaceBattleReducer 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));
}
}
La clase SpaceBattleReducer extiende la clase Reducer del marco de Hadoop. Se utiliza para realizar la agregación final de los pares clave-valor intermedios emitidos por el Mapper y, opcionalmente, procesados por el Combiner.
La clase anula el método reduce para proporcionar la lógica específica del reducer:
- El método toma una clave de tipo
Texty un iterable de valores de tipoIntWritablecomo entrada. La clave representa una palabra, y el iterable contiene los conteos de ocurrencias de esa palabra. - El método itera sobre los valores, sumándolos para obtener el recuento total de la palabra.
- Finalmente, el método emite un par clave-valor con la palabra como clave y el recuento total como valor utilizando el método
context.write.
El SpaceBattleReducer realiza la agregación final de los datos, sumando los conteos para cada palabra en todas las salidas del Mapper. Esto proporciona el recuento final de ocurrencias para cada palabra en los datos de entrada.
Escribe el Driver
En este paso, crearás un archivo Java para administrar el trabajo MapReduce, incluyendo la configuración del trabajo y la especificación de las clases Mapper, Combiner y Reducer.
Crea un archivo Java para la clase Driver:
nano /home/hadoop/SpaceBattleDriver.java
Luego, agrega el siguiente código al archivo SpaceBattleDriver.java:
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 SpaceBattleDriver {
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "Space Battle Simulation");
job.setJarByClass(SpaceBattleDriver.class);
job.setMapperClass(SpaceBattleMapper.class);
job.setCombinerClass(SpaceBattleCombiner.class);
job.setReducerClass(SpaceBattleReducer.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);
}
}
La clase SpaceBattleDriver es responsable de configurar y ejecutar el trabajo MapReduce para la simulación de batalla espacial.
La clase comienza creando un nuevo objeto
Configurationy una instancia deJobcon esta configuración. El trabajo se le da un nombre, "Space Battle Simulation", para su identificación.El método
setJarByClassse llama con la claseSpaceBattleDriverpara establecer el archivo jar que contiene las clases necesarias para el trabajo.Los métodos
setMapperClass,setCombinerClassysetReducerClassse utilizan para especificar las clases que realizarán las tareas de mapeo, combinación y reducción, respectivamente.Los métodos
setOutputKeyClassysetOutputValueClassdefinen los tipos de la clave y el valor de salida, que en este caso sonTexteIntWritable.Los métodos
FileInputFormat.addInputPathyFileOutputFormat.setOutputPathestablecen las rutas para los datos de entrada y salida. Estas rutas se pasan como argumentos de línea de comandos al método principal.Finalmente, el método
job.waitForCompletionse llama para enviar el trabajo y esperar a que se complete. El método devuelvetruesi el trabajo se completa con éxito yfalseen caso contrario. El programa sale con un código de estado de 0 si el trabajo es exitoso y 1 si no lo es.
Esta clase driver une todos los componentes del trabajo MapReduce y es el punto de entrada para ejecutar el trabajo.
Resumen
En este laboratorio, has recorrido la implementación de la técnica de Combiner de Hadoop Shuffle en un escenario de simulación de batalla espacial. Siguiendo los pasos para crear las clases Mapper, Combiner, Reducer y Driver, has adquirido experiencia práctica en la optimización del procesamiento de datos en un entorno Hadoop MapReduce. Este laboratorio tuvo como objetivo mejorar tu comprensión de la reducción del tráfico de red y la mejora de la eficiencia computacional en tareas de procesamiento de grandes datos.



