Introduction
Dans ce laboratoire, vous allez apprendre à rationaliser le processus de catalogage de la vaste collection de tomes magiques de l'illustre Académie Magique. Grâce à la puissance de Hadoop MapReduce, vous allez gérer la sérialisation des données des livres, assurant un traitement et une analyse sans heurts. Cela vous permettra de stocker et de traiter efficacement les informations sur les livres, servant finalement mieux le personnel et les étudiants de l'académie.
Implémentation de l'interface Writable
Dans cette étape, nous allons créer une classe Writable personnalisée pour représenter les données des livres. Cette classe implémentera l'interface Writable fournie par Apache Hadoop, permettant une sérialisation et une désérialisation efficaces des données pendant le processus MapReduce.
Tout d'abord, vous devez utiliser la commande su - hadoop pour devenir un utilisateur hadoop, et créer un nouveau fichier Java nommé Book.java dans le répertoire /home/hadoop avec le contenu suivant :
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.Writable;
// La classe Book représente un livre avec un titre, un auteur et une année de publication.
// Elle implémente l'interface Writable pour la sérialisation d'Hadoop.
public class Book implements Writable {
// Champs privés pour le titre, l'auteur et l'année de publication du livre.
private String title;
private String author;
private int year;
// Constructeur par défaut - requis pour créer une nouvelle instance pour la désérialisation.
public Book() {}
// Constructeur avec paramètres pour initialiser les champs avec des valeurs données.
public Book(String title, String author, int year) {
this.title = title;
this.author = author;
this.year = year;
}
// La méthode write sérialise les champs de l'objet dans le DataOutput.
public void write(DataOutput out) throws IOException {
out.writeUTF(title); // Écrit le titre au format UTF-8
out.writeUTF(author); // Écrit l'auteur au format UTF-8
out.writeInt(year); // Écrit l'année de publication sous forme d'un entier
}
// La méthode readFields désérialise les champs de l'objet à partir du DataInput.
public void readFields(DataInput in) throws IOException {
title = in.readUTF(); // Lit le titre au format UTF-8
author = in.readUTF(); // Lit l'auteur au format UTF-8
year = in.readInt(); // Lit l'année de publication sous forme d'un entier
}
// La méthode toString fournit une représentation textuelle de l'objet,
// qui est utile pour l'affichage et la journalisation.
@Override
public String toString() {
return "Titre : " + title + ", Auteur : " + author + ", Année : " + year;
}
// Les getters et setters sont omis pour la brièveté mais sont nécessaires pour accéder aux champs.
}
Cette classe Book contient des champs pour le titre, l'auteur et l'année de publication du livre. La méthode write sérialise les données du livre en un flux binaire, tandis que la méthode readFields désérialise les données à partir d'un flux binaire. Les deux méthodes sont requises par l'interface Writable.
Ensuite, vous devrez compiler les classes Java en utilisant les commandes suivantes :
## Compile les classes 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:. Book.java
Implémentation des classes Mapper et Reducer
Dans cette étape, nous allons créer une classe Mapper et une classe Reducer pour traiter les données des livres en utilisant le paradigme MapReduce.
BookMapper personnalisé
Tout d'abord, créez un nouveau fichier Java nommé BookMapper.java dans le répertoire /home/hadoop avec le contenu suivant :
import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
// BookMapper étend la classe Mapper pour traiter les fichiers d'entrée texte
// Les paires clé-valeur d'entrée sont LongWritable (numéro de ligne) et Text (contenu de ligne)
// Les paires clé-valeur de sortie sont Text (nom de l'auteur) et Book (détails du livre)
public class BookMapper extends Mapper<LongWritable, Text, Text, Book> {
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
// Divisez la ligne d'entrée par virgule
String[] bookData = value.toString().split(",");
// Extrait le titre, l'auteur et l'année de la ligne d'entrée
String title = bookData[0];
String author = bookData[1];
int year = Integer.parseInt(bookData[2]);
// Écrivez l'auteur et les détails du livre dans le contexte
context.write(new Text(author), new Book(title, author, year));
}
}
Cette classe BookMapper prend une ligne de données d'entrée au format "titre,auteur,année" et émet une paire clé-valeur avec l'auteur comme clé et un objet Book comme valeur.
BookReducer personnalisé
Ensuite, créez un nouveau fichier Java nommé BookReducer.java dans le répertoire /home/hadoop avec le contenu suivant :
import java.io.IOException;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
// BookReducer étend la classe Reducer pour regrouper les détails des livres par auteur
// Les paires clé-valeur d'entrée sont Text (nom de l'auteur) et Book (détails du livre)
// Les paires clé-valeur de sortie sont Text (nom de l'auteur) et Book (détails des livres regroupés)
public class BookReducer extends Reducer<Text, Book, Text, Book> {
@Override
protected void reduce(Text key, Iterable<Book> values, Context context) throws IOException, InterruptedException {
// Parcourez les livres pour le même auteur et écrivez chaque livre dans le contexte
for (Book book : values) {
context.write(key, book);
}
}
}
Cette classe BookReducer émet simplement les paires clé-valeur d'entrée telles quelles, regroupant ainsi les livres par auteur.
Compiler les fichiers
Finalement, vous devrez compiler les classes Java en utilisant les commandes suivantes :
## Compile les classes 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:. BookMapper.java BookReducer.java
Exécution du travail MapReduce
Dans cette étape, nous allons créer une classe Driver pour exécuter le travail MapReduce et traiter les données des livres.
BookDriver personnalisé
Tout d'abord, créez un nouveau fichier Java nommé BookDriver.java dans le répertoire /home/hadoop avec le contenu suivant :
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;
// BookDriver configure et soumet le travail MapReduce
public class BookDriver {
public static void main(String[] args) throws Exception {
// Crée une nouvelle configuration de travail Hadoop
Configuration conf = new Configuration();
// Instancie un objet Job avec la configuration de travail
Job job = Job.getInstance(conf, "Traitement des livres");
// Spécifie le fichier JAR du travail par classe
job.setJarByClass(BookDriver.class);
// Définit la classe Mapper du travail
job.setMapperClass(BookMapper.class);
// Définit la classe Reducer du travail
job.setReducerClass(BookReducer.class);
// Définit la classe de clé de sortie du travail
job.setOutputKeyClass(Text.class);
// Définit la classe de valeur de sortie du travail
job.setOutputValueClass(Book.class);
// Définit le chemin d'entrée du travail
FileInputFormat.addInputPath(job, new Path(args[0]));
// Définit le chemin de sortie du travail
FileOutputFormat.setOutputPath(job, new Path(args[1]));
// Sortie avec le statut de fin du travail
System.exit(job.waitForCompletion(true)? 0 : 1);
}
}
Cette classe BookDriver configure et exécute le travail MapReduce. Elle configure le travail avec les classes BookMapper et BookReducer, définit les chemins d'entrée et de sortie, et attend que le travail se termine.
Exécution du travail
Pour exécuter le travail MapReduce, vous devrez compiler les classes Java et créer un fichier JAR. Vous pouvez utiliser les commandes suivantes :
## Compile les classes 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:. BookDriver.java
## Crée un fichier JAR
jar -cvf book.jar *.class
Ensuite, vous devrez créer un répertoire d'entrée et copier quelques données d'échantillons de livres dedans. Vous pouvez utiliser les commandes suivantes :
## Crée un répertoire d'entrée
hdfs dfs -mkdir /input
## Copie les données d'échantillons dans le répertoire d'entrée
hdfs dfs -put./data.txt /input
Enfin, vous pouvez exécuter le travail MapReduce en utilisant la commande suivante :
hadoop jar book.jar BookDriver /input /output
Cette commande exécutera la classe BookDriver, en utilisant les données d'entrée de /input et en sortant les résultats vers /output. Vous pouvez visualiser le résultat avec la commande suivante.
hdfs dfs -cat /output/part-r-00000
Résumé
Félicitations ! Vous avez réussi à maîtriser la sérialisation dans Hadoop MapReduce en créant des classes Writable personnalisées. Dans le cadre d'un scénario où le bibliothécaire principal d'une académie magique gère une vaste collection de livres, vous avez conçu une classe Book implémentant l'interface Writable pour une sérialisation et une désérialisation de données sans heurts. En créant une classe BookMapper pour extraire les informations sur les livres et une classe BookReducer pour regrouper efficacement les livres par auteur, vous avez orchestré le processus avec une classe BookDriver. Cela a impliqué des tâches telles que la compilation des classes Java, la création d'un fichier JAR et l'exécution du travail sur le cluster Hadoop. Au fil du chemin, vous avez acquis une expérience précieuse en Hadoop MapReduce, en affinant vos compétences dans les classes Writable personnalisées, les classes Mapper et Reducer, et en orchestrant les travaux MapReduce pour les tâches de traitement de données à grande échelle.



