El Marc MapReduce és un dels components fonamentals de l'ecosistema Hadoop. És un model de programació i una plataforma de processament que permet processar grans volums de dades de manera distribuïda i paral·lela. En aquesta secció, explorarem els conceptes clau del Marc MapReduce, la seva arquitectura, i com escriure i executar programes MapReduce.

Conceptes Clau de MapReduce

  1. Model de Programació

MapReduce es basa en dos passos principals:

  • Map: Aquest pas pren un conjunt de dades d'entrada i el transforma en un conjunt de parells clau-valor intermedi.
  • Reduce: Aquest pas pren els parells clau-valor intermedis generats pel pas Map i els combina per produir un conjunt de resultats finals.

  1. Funcions Map i Reduce

  • Funció Map: Processa un registre d'entrada a la vegada i genera zero o més parells clau-valor intermedis.
  • Funció Reduce: Agrega els parells clau-valor intermedis amb la mateixa clau i genera el resultat final.

  1. Divisió de Treball

MapReduce divideix el treball en tasques més petites que es poden executar en paral·lel en diferents nodes del clúster Hadoop.

Arquitectura de MapReduce

Components Principals

  • JobTracker: Coordina la distribució de les tasques Map i Reduce als nodes del clúster.
  • TaskTracker: Executa les tasques Map i Reduce assignades pel JobTracker.
  • InputFormat: Defineix com es llegeixen les dades d'entrada.
  • OutputFormat: Defineix com s'escriuen les dades de sortida.

Flux de Treball de MapReduce

  1. Divisió de Dades: Les dades d'entrada es divideixen en fragments més petits.
  2. Assignació de Tasques: El JobTracker assigna tasques Map als TaskTrackers.
  3. Execució de Map: Els TaskTrackers executen les tasques Map i generen parells clau-valor intermedis.
  4. Partició i Ordenació: Els parells clau-valor intermedis es particionen i ordenen per clau.
  5. Assignació de Tasques Reduce: El JobTracker assigna tasques Reduce als TaskTrackers.
  6. Execució de Reduce: Els TaskTrackers executen les tasques Reduce i generen els resultats finals.

Exemple Pràctic: Programa MapReduce

Problema: Comptar la freqüència de paraules en un conjunt de documents

1. Funció Map

import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.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 {
        String[] words = value.toString().split("\\s+");
        for (String str : words) {
            word.set(str);
            context.write(word, one);
        }
    }
}

Explicació:

  • Entrada: Clau (offset del fitxer), Valor (línia de text).
  • Sortida: Clau (paraula), Valor (1).

2. Funció Reduce

import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.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));
    }
}

Explicació:

  • Entrada: Clau (paraula), Valor (iterable d'1s).
  • Sortida: Clau (paraula), Valor (comptador total).

3. Programa Principal

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 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);
    }
}

Explicació:

  • Configuració del Job: Es defineixen les classes Mapper, Reducer, i les rutes d'entrada i sortida.

Exercici Pràctic

Exercici: Comptar la freqüència de caràcters en un conjunt de documents

1. Escriu la funció Map

  • Entrada: Clau (offset del fitxer), Valor (línia de text).
  • Sortida: Clau (caràcter), Valor (1).

2. Escriu la funció Reduce

  • Entrada: Clau (caràcter), Valor (iterable d'1s).
  • Sortida: Clau (caràcter), Valor (comptador total).

3. Escriu el programa principal

  • Configura el Job per utilitzar les funcions Map i Reduce que has escrit.

Solució

Funció Map

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

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

    public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        char[] chars = value.toString().toCharArray();
        for (char c : chars) {
            character.set(Character.toString(c));
            context.write(character, one);
        }
    }
}

Funció Reduce

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

public class CharCountReducer 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));
    }
}

Programa Principal

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 CharCount {
    public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf, "char count");
        job.setJarByClass(CharCount.class);
        job.setMapperClass(CharCountMapper.class);
        job.setCombinerClass(CharCountReducer.class);
        job.setReducerClass(CharCountReducer.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);
    }
}

Conclusió

En aquesta secció, hem explorat el Marc MapReduce, incloent-hi els seus conceptes clau, l'arquitectura i un exemple pràctic de com escriure un programa MapReduce per comptar la freqüència de paraules. També hem proporcionat un exercici pràctic per comptar la freqüència de caràcters, amb la seva solució. Amb aquests coneixements, estàs preparat per començar a escriure els teus propis programes MapReduce i processar grans volums de dades de manera eficient.

© Copyright 2024. Tots els drets reservats