Búsqueda de Descubrimiento de Datos del Desierto

HadoopHadoopBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En la vasta extensión de un desierto árido, un solitario mercader emprende un peligroso viaje, buscando desentrañar los misterios escondidos debajo de las abrasadoras arenas. El objetivo del mercader es descubrir reliquias y artefactos antiguos, desbloqueando los secretos de una civilización olvidada hace mucho tiempo. Sin embargo, la gran cantidad de datos enterrados en el desierto plantea un formidable desafío, requiriendo el poder de Hadoop MapReduce para procesar y analizar efectivamente la información.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL hadoop(("Hadoop")) -.-> hadoop/HadoopMapReduceGroup(["Hadoop MapReduce"]) hadoop(("Hadoop")) -.-> hadoop/HadoopYARNGroup(["Hadoop YARN"]) hadoop(("Hadoop")) -.-> hadoop/HadoopHiveGroup(["Hadoop Hive"]) hadoop/HadoopMapReduceGroup -.-> hadoop/setup_jobs("Setting up MapReduce Jobs") hadoop/HadoopMapReduceGroup -.-> hadoop/mappers_reducers("Coding Mappers and Reducers") hadoop/HadoopYARNGroup -.-> hadoop/yarn_jar("Yarn Commands jar") hadoop/HadoopHiveGroup -.-> hadoop/process("Process Control Function") hadoop/HadoopHiveGroup -.-> hadoop/aggregating("Aggregating Function") hadoop/HadoopHiveGroup -.-> hadoop/udf("User Defined Function") subgraph Lab Skills hadoop/setup_jobs -.-> lab-288986{{"Búsqueda de Descubrimiento de Datos del Desierto"}} hadoop/mappers_reducers -.-> lab-288986{{"Búsqueda de Descubrimiento de Datos del Desierto"}} hadoop/yarn_jar -.-> lab-288986{{"Búsqueda de Descubrimiento de Datos del Desierto"}} hadoop/process -.-> lab-288986{{"Búsqueda de Descubrimiento de Datos del Desierto"}} hadoop/aggregating -.-> lab-288986{{"Búsqueda de Descubrimiento de Datos del Desierto"}} hadoop/udf -.-> lab-288986{{"Búsqueda de Descubrimiento de Datos del Desierto"}} end

Implementando el Mapper

En este paso, crearemos una clase Mapper para procesar los datos crudos obtenidos de las excavaciones en el desierto. Nuestro objetivo es extraer la información relevante de los datos y prepararla para su análisis ulterior por el Reducer.

Utilice el comando su - hadoop para cambiar al usuario hadoop y automáticamente ir al directorio /home/hadoop. En este momento, use el comando ls. para ver el archivo de datos data*.txt. Luego cree y complete el archivo ArtifactMapper.java en ese directorio de acuerdo con el código siguiente:

import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

public class ArtifactMapper extends Mapper<LongWritable, Text, Text, LongWritable> {

    private final static LongWritable ONE = new LongWritable(1);
    private Text word = new Text();

    @Override
    public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        // Divide la línea en palabras
        String[] tokens = value.toString().split("\\s+");

        // Emite cada palabra con un recuento de 1
        for (String token : tokens) {
            word.set(token);
            context.write(word, ONE);
        }
    }
}

En la clase ArtifactMapper, extendemos la clase Mapper proporcionada por Hadoop. Se anula el método map para procesar cada par clave-valor de entrada.

  1. La clave de entrada es un LongWritable que representa el desplazamiento de bytes de la línea de entrada, y el valor de entrada es un objeto Text que contiene la línea de texto del archivo de entrada.
  2. El método map divide la línea de entrada en palabras individuales utilizando el método split y la expresión regular "\\s+" para coincidir con uno o más caracteres de espacio en blanco.
  3. Para cada palabra, el método map crea un objeto Text y lo emite como clave, junto con un valor LongWritable constante de 1 como valor, que representa el recuento de esa palabra.

Implementando el Reducer

En este paso, crearemos una clase Reducer para agregar los datos emitidos por el Mapper. El Reducer contará la frecuencia de cada palabra y producirá la salida final.

Cree y complete el archivo ArtifactReducer.java en el directorio /home/hadoop de acuerdo con el siguiente contenido de código:

import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

public class ArtifactReducer extends Reducer<Text, LongWritable, Text, LongWritable> {

    @Override
    public void reduce(Text key, Iterable<LongWritable> values, Context context)
            throws IOException, InterruptedException {
        long sum = 0;
        for (LongWritable value : values) {
            sum += value.get();
        }
        context.write(key, new LongWritable(sum));
    }
}

En la clase ArtifactReducer, extendemos la clase Reducer proporcionada por Hadoop. Se anula el método reduce para agregar los valores asociados con cada clave.

  1. La clave de entrada es un objeto Text que representa la palabra, y los valores de entrada son un Iterable de objetos LongWritable que representan los recuentos de esa palabra emitidos por los Mappers.
  2. El método reduce itera sobre los valores y calcula la suma de todos los recuentos para la palabra dada.
  3. El método reduce luego emite la palabra como clave y el recuento total como valor, utilizando context.write.

Creando el Controlador

En este paso, crearemos una clase Controlador para coordinar el trabajo MapReduce. El Controlador configurará el trabajo, especificará las rutas de entrada y salida y enviará el trabajo al clúster de Hadoop.

Cree y complete el archivo ArtifactDriver.java en el directorio /home/hadoop de acuerdo con el siguiente contenido de código:

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
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 ArtifactDriver {

    public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf, "Artifact Word Count");

        // Especifique el archivo jar del trabajo por clase
        job.setJarByClass(ArtifactDriver.class);

        // Establezca las clases Mapper y Reducer
        job.setMapperClass(ArtifactMapper.class);
        job.setReducerClass(ArtifactReducer.class);

        // Establezca los tipos de clave y valor de salida
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(LongWritable.class);

        // Establezca las rutas de entrada y salida
        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        // Envíe el trabajo y espere a que se complete
        System.exit(job.waitForCompletion(true)? 0 : 1);
    }
}

En la clase ArtifactDriver, creamos un trabajo MapReduce y lo configuramos para ejecutar nuestras clases ArtifactMapper y ArtifactReducer.

  1. El método main crea un nuevo objeto Configuration y un objeto Job con un nombre personalizado "Artifact Word Count".
  2. Los métodos setMapperClass y setReducerClass se utilizan para especificar las clases Mapper y Reducer que se utilizarán en el trabajo.
  3. Los métodos setOutputKeyClass y setOutputValueClass se utilizan para especificar los tipos de clave y valor de salida para el trabajo.
  4. El método FileInputFormat.addInputPath se utiliza para especificar la ruta de entrada para el trabajo, que se toma como el primer argumento de línea de comandos.
  5. El método FileOutputFormat.setOutputPath se utiliza para especificar la ruta de salida para el trabajo, que se toma como el segundo argumento de línea de comandos.
  6. El método job.waitForCompletion se llama para enviar el trabajo y esperar a que se complete. El programa sale con un código de estado de 0 si el trabajo es exitoso, o 1 si falla.

Compilando y Ejecutando el Trabajo

En este paso, compilaremos las clases Java y ejecutaremos el trabajo MapReduce en el clúster de Hadoop.

Primero, necesitamos compilar las clases Java:

javac -source 8 -target 8 -classpath $HADOOP_HOME/share/hadoop/common/hadoop-common-3.3.6.jar:$HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-client-core-3.3.6.jar:. *.java

Este comando compila las clases Java y coloca los archivos .class compilados en el directorio actual. La opción -classpath incluye las rutas de la biblioteca de Hadoop, que se necesitan para compilar el código que utiliza clases de Hadoop. Los parámetros -source y -target se utilizan para especificar las versiones de código fuente y bytecode objetivo de Java para coincidir con la versión de Java en Hadoop

Luego, empaquetamos los archivos class con el comando jar:

jar -cvf Artifact.jar *.class

Finalmente, podemos ejecutar el trabajo MapReduce, y todos los datos sobre el desierto ya están almacenados en el directorio HDFS /input:

hadoop jar Artifact.jar ArtifactDriver /input /output

Después de ejecutar el comando, debería ver registros que indican el progreso del trabajo MapReduce. Una vez que el trabajo se complete, puede encontrar los archivos de salida en el directorio HDFS /output. Y use el siguiente comando para ver el resultado:

hdfs dfs -ls /output
hdfs dfs -cat /output/part-r-00000

Resumen

¡Felicidades! Has explorado con éxito el proceso de codificación de Mappers y Reducers para un trabajo MapReduce de Hadoop. Guiado por un escenario en el que un comerciante del desierto busca reliquias antiguas, has aprovechado el poder de Hadoop MapReduce para analizar grandes cantidades de datos del desierto. La implementación de la clase ArtifactMapper extrajo los datos relevantes, mientras que la clase ArtifactReducer agregó la salida del Mapper. La coordinación del proceso con la clase ArtifactDriver consolidó aún más tu comprensión. En todo momento, se puso énfasis en las mejores prácticas, ejemplos completos de código y verificaciones. Esta experiencia práctica profundizó tu comprensión de Hadoop MapReduce y destacó el diseño de una experiencia de aprendizaje efectiva.