Hadoop Shuffle Combiner

HadoopBeginner
Practicar Ahora

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 objeto IntWritable con un valor constante de 1. Esto se utiliza como el valor en los pares clave-valor emitidos.
  • word: Un objeto Text utilizado 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 Text se 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 word se establece en esa palabra, y se emite un par clave-valor con la palabra como clave y one como valor. Esto se hace utilizando el método context.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 Text y un iterable de valores de tipo IntWritable como 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.

  1. 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 Text y un iterable de valores de tipo IntWritable como 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 Configuration y una instancia de Job con esta configuración. El trabajo se le da un nombre, "Space Battle Simulation", para su identificación.

  • El método setJarByClass se llama con la clase SpaceBattleDriver para establecer el archivo jar que contiene las clases necesarias para el trabajo.

  • Los métodos setMapperClass, setCombinerClass y setReducerClass se utilizan para especificar las clases que realizarán las tareas de mapeo, combinación y reducción, respectivamente.

  • Los métodos setOutputKeyClass y setOutputValueClass definen los tipos de la clave y el valor de salida, que en este caso son Text e IntWritable.

  • Los métodos FileInputFormat.addInputPath y FileOutputFormat.setOutputPath establecen 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.waitForCompletion se llama para enviar el trabajo y esperar a que se complete. El método devuelve true si el trabajo se completa con éxito y false en 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.