Partitionnement Olympique avec Hadoop

HadoopHadoopBeginner
Pratiquer maintenant

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Dans l'Olympiade grecque antique, des athlètes venus de tout le pays se réunissaient pour démontrer leur force et concourir dans diverses épreuves sportives. Un tel athlète, Alexios, avait entraîné sans relâche pour les prochains jeux, déterminé à apporter la gloire à sa cité-État.

L'objectif était de trier et d'organiser les participants en différents groupes selon leurs épreuves, afin de garantir une compétition juste et efficace. Cependant, avec des centaines d'athlètes concourant pour la gloire, la tâche de les répartir dans leurs épreuves respectives était redoutable.


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/mappers_reducers("Coding Mappers and Reducers") hadoop/HadoopMapReduceGroup -.-> hadoop/shuffle_partitioner("Shuffle Partitioner") hadoop/HadoopYARNGroup -.-> hadoop/yarn_setup("Hadoop YARN Basic Setup") hadoop/HadoopHiveGroup -.-> hadoop/process("Process Control Function") hadoop/HadoopHiveGroup -.-> hadoop/udf("User Defined Function") hadoop/HadoopHiveGroup -.-> hadoop/integration("Integration with HDFS and MapReduce") subgraph Lab Skills hadoop/mappers_reducers -.-> lab-288997{{"Partitionnement Olympique avec Hadoop"}} hadoop/shuffle_partitioner -.-> lab-288997{{"Partitionnement Olympique avec Hadoop"}} hadoop/yarn_setup -.-> lab-288997{{"Partitionnement Olympique avec Hadoop"}} hadoop/process -.-> lab-288997{{"Partitionnement Olympique avec Hadoop"}} hadoop/udf -.-> lab-288997{{"Partitionnement Olympique avec Hadoop"}} hadoop/integration -.-> lab-288997{{"Partitionnement Olympique avec Hadoop"}} end

Implémentez le Mapper

Dans cette étape, nous allons créer une classe Mapper qui lit les données d'entrée et génère des paires clé-valeur pour le Partitioner à traiter.

Tout d'abord, changez l'utilisateur en hadoop puis accédez au répertoire racine de l'utilisateur hadoop:

su - hadoop

Ensuite, créez un fichier Java pour la classe Mapper:

touch /home/hadoop/OlympicMapper.java

Ajoutez le code suivant au fichier OlympicMapper.java:

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

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

    @Override
    protected void map(LongWritable key, Text value, Context context)
            throws IOException, InterruptedException {
        String[] fields = value.toString().split(",");
        String athlete = fields[0];
        String event = fields[1];
        context.write(new Text(event), new Text(athlete));
    }
}

Dans la classe OlympicMapper, nous définissons la clé d'entrée comme LongWritable (représentant le décalage de ligne) et la valeur d'entrée comme Text (représentant une ligne de texte du fichier d'entrée). La clé de sortie est un objet Text représentant l'événement, et la valeur de sortie est un objet Text représentant le nom de l'athlète.

La méthode map divise chaque ligne de données d'entrée par le délimiteur virgule, extrait le nom de l'athlète et l'événement, et émet une paire clé-valeur avec l'événement comme clé et le nom de l'athlète comme valeur.

Implémentez le Partitioner

Dans cette étape, nous allons créer une classe Partitioner personnalisée qui partitionne les paires clé-valeur en fonction de l'événement.

Tout d'abord, créez un fichier Java pour la classe Partitioner:

touch /home/hadoop/OlympicPartitioner.java

Ensuite, ajoutez le code suivant au fichier OlympicPartitioner.java:

import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Partitioner;

public class OlympicPartitioner extends Partitioner<Text, Text> {

    @Override
    public int getPartition(Text key, Text value, int numPartitions) {
        return Math.abs(key.hashCode() % numPartitions);
    }
}

La classe OlympicPartitioner étend la classe Partitioner fournie par Hadoop. Elle redéfinit la méthode getPartition, qui prend la clé, la valeur et le nombre de partitions en entrée.

La méthode getPartition calcule un code de hachage pour l'événement (clé) et renvoie le numéro de partition en prenant la valeur absolue du code de hachage modulo le nombre de partitions. Cela garantit que tous les enregistrements avec le même événement sont envoyés à la même partition pour être traités par le Réducteur.

Implémentez le Réducteur

Dans cette étape, nous allons créer une classe Réducteur qui traite les données partitionnées et génère la sortie finale.

Tout d'abord, créez un fichier Java pour la classe Réducteur:

touch /home/hadoop/OlympicReducer.java

Ensuite, ajoutez le code suivant au fichier OlympicReducer.java:

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

public class OlympicReducer extends Reducer<Text, Text, Text, Text> {

    @Override
    protected void reduce(Text key, Iterable<Text> values, Context context)
            throws IOException, InterruptedException {
        StringBuilder athletes = new StringBuilder();
        for (Text value : values) {
            athletes.append(value.toString()).append(",");
        }
        if (athletes.length() > 0) {
            athletes.deleteCharAt(athletes.length() - 1);
        }
        context.write(key, new Text(athletes.toString()));
    }
}

La classe OlympicReducer étend la classe Reducer fournie par Hadoop. Elle définit la clé d'entrée comme Text (représentant l'événement), la valeur d'entrée comme Text (représentant le nom de l'athlète), et la clé et la valeur de sortie comme des objets Text.

La méthode reduce est appelée pour chaque clé d'événement unique, avec un itérateur sur les noms d'athlètes associés à cet événement. Elle construit une liste séparée par des virgules d'athlètes pour chaque événement et émet une paire clé-valeur avec l'événement comme clé et la liste d'athlètes comme valeur.

Écrivez le Pilote

Dans cette étape, nous allons créer une classe Pilote qui lie les classes Mapper, Partitioner et Reducer et exécute le travail MapReduce.

Tout d'abord, créez un fichier Java pour la classe Pilote:

touch /home/hadoop/OlympicDriver.java

Ensuite, ajoutez le code suivant au fichier OlympicDriver.java:

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

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

        job.setJarByClass(OlympicDriver.class);
        job.setMapperClass(OlympicMapper.class);
        job.setPartitionerClass(OlympicPartitioner.class);
        job.setReducerClass(OlympicReducer.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);

        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        System.exit(job.waitForCompletion(true)? 0 : 1);
    }
}

La classe OlympicDriver est le point d'entrée du travail MapReduce. Elle configure la configuration du travail, spécifie les classes Mapper, Partitioner et Reducer et configure les chemins d'entrée et de sortie.

Dans la méthode main, nous créons un nouvel objet Configuration et une instance de Job avec le nom de travail "Olympic Partitioner". Nous définissons les classes Mapper, Partitioner et Reducer en utilisant les méthodes de définition correspondantes.

Nous définissons également les classes de clé et de valeur de sortie sur Text. Les chemins d'entrée et de sortie sont spécifiés en utilisant les arguments de ligne de commande passés au pilote.

Enfin, nous appelons la méthode waitForCompletion sur l'instance Job pour exécuter le travail MapReduce et sortir avec un code de statut approprié (0 pour la réussite, 1 pour l'échec).

Pour exécuter le travail, vous devez compiler les classes Java et créer un fichier jar. Ensuite, vous pouvez exécuter le fichier jar en utilisant la commande suivante:

javac -source 8 -target 8 -classpath "/home/hadoop/:/home/hadoop/hadoop/share/hadoop/common/hadoop-common-3.3.6.jar:/home/hadoop/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-core-3.3.6.jar:/home/hadoop/hadoop/share/hadoop/common/lib/*" -d /home/hadoop /home/hadoop/OlympicMapper.java /home/hadoop/OlympicPartitioner.java /home/hadoop/OlympicReducer.java /home/hadoop/OlympicDriver.java
jar cvf olympic.jar *.class
hadoop jar olympic.jar OlympicDriver /input /output

Enfin, nous pouvons vérifier les résultats en exécutant la commande suivante:

hadoop fs -cat /output/*

Sortie exemple:

Event_1 Athlete_17,Athlete_18,Athlete_79,Athlete_71,Athlete_77,Athlete_75,Athlete_19,Athlete_24,Athlete_31,Athlete_32,Athlete_39,Athlete_89,Athlete_88,Athlete_87,Athlete_100,Athlete_13,Athlete_52,Athlete_53,Athlete_58
Event_2 Athlete_1,Athlete_97,Athlete_96,Athlete_85,Athlete_81,Athlete_80,Athlete_72,Athlete_68,Athlete_64,Athlete_61,Athlete_54,Athlete_48,Athlete_47,Athlete_43,Athlete_28,Athlete_23,Athlete_21,Athlete_15,Athlete_12,Athlete_3
Event_3 Athlete_11,Athlete_55,Athlete_8,Athlete_46,Athlete_42,Athlete_41,Athlete_40,Athlete_38,Athlete_33,Athlete_92,Athlete_29,Athlete_27,Athlete_25,Athlete_93,Athlete_22,Athlete_20,Athlete_98,Athlete_14,Athlete_69,Athlete_99,Athlete_66,Athlete_65
Event_4 Athlete_90,Athlete_50,Athlete_37,Athlete_36,Athlete_91,Athlete_74,Athlete_73,Athlete_63,Athlete_26,Athlete_78,Athlete_5,Athlete_62,Athlete_60,Athlete_59,Athlete_82,Athlete_4,Athlete_51,Athlete_86,Athlete_2,Athlete_94,Athlete_7,Athlete_95
Event_5 Athlete_34,Athlete_76,Athlete_57,Athlete_56,Athlete_30,Athlete_16,Athlete_6,Athlete_10,Athlete_83,Athlete_84,Athlete_70,Athlete_45,Athlete_44,Athlete_49,Athlete_9,Athlete_67,Athlete_35

Sommaire

Dans ce laboratoire, nous avons exploré le concept du Partitioner de triage Hadoop en concevant un scénario inspiré des Olympiades grecques antiques. Nous avons implémenté une classe Mapper pour lire les données d'entrée et générer des paires clé-valeur, une classe Partitioner personnalisée pour partitionner les données en fonction de l'événement, et une classe Réducteur pour traiter les données partitionnées et générer la sortie finale.

Grâce à ce laboratoire, j'ai acquis une expérience pratique du modèle de programmation MapReduce et j'ai appris à utiliser la classe Partitioner pour distribuer efficacement les données entre les partitions. Le scénario des Olympiades grecques antiques a fourni un contexte captivant pour comprendre les applications pratiques du Partitioner de triage dans un contexte réel.