Què és MapReduce?

MapReduce és un model de programació i una plataforma de processament de dades distribuïdes desenvolupada per Google. És una de les peces fonamentals de l'ecosistema Hadoop i permet processar grans volums de dades de manera paral·lela i distribuïda. El model es basa en dos passos principals: Map i Reduce.

Components clau de MapReduce

  1. Map: Aquest pas pren un conjunt de dades d'entrada i el transforma en un conjunt de parells clau-valor intermedi.
  2. Shuffle and Sort: Aquest pas reordena els parells clau-valor intermedis per clau, agrupant tots els valors associats amb la mateixa clau.
  3. Reduce: Aquest pas pren els parells clau-valor intermedis agrupats i els processa per produir el conjunt de dades de sortida final.

Funcionament de MapReduce

Pas 1: Map

El pas Map és responsable de processar les dades d'entrada i generar parells clau-valor intermedis. Cada registre d'entrada és processat per una funció Map que genera zero o més parells clau-valor intermedis.

Exemple de codi Map:

public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
    private final static IntWritable one = new IntWritable(1);
    private Text word = new Text();

    public void map(LongWritable 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);
        }
    }
}

Explicació:

  • LongWritable key: La clau d'entrada, que és la posició del registre dins del fitxer.
  • Text value: El valor d'entrada, que és una línia de text.
  • Context context: L'objecte que permet escriure els parells clau-valor intermedis.
  • StringTokenizer: Divideix la línia de text en paraules.
  • context.write(word, one): Escriu cada paraula com a clau i el número 1 com a valor.

Pas 2: Shuffle and Sort

Aquest pas és gestionat automàticament pel framework Hadoop. Reordena els parells clau-valor intermedis per clau i els agrupa.

Pas 3: Reduce

El pas Reduce pren els parells clau-valor intermedis agrupats i els processa per produir el conjunt de dades de sortida final. La funció Reduce rep una clau i una llista de valors associats amb aquesta clau.

Exemple de codi Reduce:

public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
    public 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));
    }
}

Explicació:

  • Text key: La clau d'entrada, que és una paraula.
  • Iterable values: La llista de valors associats amb la clau.
  • context.write(key, new IntWritable(sum)): Escriu la clau i la suma dels valors com a sortida.

Flux de treball d'una feina MapReduce

  1. Lectura de dades d'entrada: Les dades d'entrada es llegeixen des del sistema de fitxers distribuït (HDFS).
  2. Execució del pas Map: Les dades d'entrada es divideixen en fragments i es processen en paral·lel per les funcions Map.
  3. Shuffle and Sort: Els parells clau-valor intermedis es reordenen i agrupen per clau.
  4. Execució del pas Reduce: Els parells clau-valor agrupats es processen per les funcions Reduce.
  5. Escritura de dades de sortida: Les dades de sortida es guarden al sistema de fitxers distribuït (HDFS).

Exercici pràctic

Objectiu

Implementar un programa MapReduce per comptar la freqüència de paraules en un conjunt de documents.

Passos

  1. Escriu la classe Mapper per dividir les línies de text en paraules.
  2. Escriu la classe Reducer per sumar les freqüències de les paraules.
  3. Configura i executa la feina MapReduce.

Solució

Classe Mapper:

public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
    private final static IntWritable one = new IntWritable(1);
    private Text word = new Text();

    public void map(LongWritable 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);
        }
    }
}

Classe Reducer:

public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
    public 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));
    }
}

Classe Driver:

public class WordCount {
    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(WordCountMapper.class);
        job.setCombinerClass(WordCountReducer.class);
        job.setReducerClass(WordCountReducer.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);
    }
}

Execució

  1. Compila les classes Java.
  2. Executa la feina MapReduce amb les dades d'entrada i la ruta de sortida especificades.

Conclusió

En aquesta secció, hem introduït el model de programació MapReduce, hem explicat els passos clau del seu funcionament i hem proporcionat un exemple pràctic de comptatge de paraules. Aquest coneixement és fonamental per comprendre com processar grans volums de dades de manera eficient amb Hadoop. En la següent secció, explorarem el flux de treball d'una feina MapReduce en més detall.

© Copyright 2024. Tots els drets reservats