Einführung
In diesem Lab werden Sie lernen, wie Sie den Katalogisierungsprozess für die umfangreiche Sammlung magischer Bücher an der renommierten Magischen Akademie vereinfachen. Mit der Macht von Hadoop MapReduce werden Sie die Serialisierung von Buchdaten handhaben und so eine nahtlose Verarbeitung und Analyse gewährleisten. Dadurch können Sie die Buchinformationen effizient speichern und verarbeiten und letztendlich der Fakultät und den Studenten der Akademie besser dienen.
Implementierung der Writable-Schnittstelle
In diesem Schritt werden wir eine benutzerdefinierte Writable-Klasse erstellen, um die Buchdaten zu repräsentieren. Diese Klasse wird die von Apache Hadoop bereitgestellte Writable-Schnittstelle implementieren, was eine effiziente Serialisierung und Deserialisierung der Daten während des MapReduce-Prozesses ermöglicht.
Zunächst müssen Sie den Befehl su - hadoop verwenden, um sich als hadoop-Benutzer zu authentifizieren, und eine neue Java-Datei mit dem Namen Book.java im Verzeichnis /home/hadoop mit den folgenden Inhalten erstellen:
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.Writable;
// Die Book-Klasse repräsentiert ein Buch mit einem Titel, einem Autor und einem Erscheinungsjahr.
// Sie implementiert die Writable-Schnittstelle für die Serialisierung in Hadoop.
public class Book implements Writable {
// Private Felder für den Titel, den Autor und das Erscheinungsjahr des Buches.
private String title;
private String author;
private int year;
// Standardkonstruktor - erforderlich für das Erstellen einer neuen Instanz für die Deserialisierung.
public Book() {}
// Konstruktor mit Parametern, um die Felder mit angegebenen Werten zu initialisieren.
public Book(String title, String author, int year) {
this.title = title;
this.author = author;
this.year = year;
}
// Die write-Methode serialisiert die Felder des Objekts in das DataOutput.
public void write(DataOutput out) throws IOException {
out.writeUTF(title); // Schreibt den Titel als UTF-8
out.writeUTF(author); // Schreibt den Autor als UTF-8
out.writeInt(year); // Schreibt das Erscheinungsjahr als Ganzzahl
}
// Die readFields-Methode deserialisiert die Felder des Objekts aus dem DataInput.
public void readFields(DataInput in) throws IOException {
title = in.readUTF(); // Liest den Titel als UTF-8
author = in.readUTF(); // Liest den Autor als UTF-8
year = in.readInt(); // Liest das Erscheinungsjahr als Ganzzahl
}
// Die toString-Methode liefert eine Zeichenfolgendarstellung des Objekts,
// die für das Drucken und das Protokollieren nützlich ist.
@Override
public String toString() {
return "Title: " + title + ", Author: " + author + ", Year: " + year;
}
// Getter- und Setter-Methoden werden aus Gründen der Kürze weggelassen, sind aber erforderlich, um auf die Felder zuzugreifen.
}
Diese Book-Klasse enthält Felder für den Titel, den Autor und das Erscheinungsjahr des Buches. Die write-Methode serialisiert die Buchdaten in einen Byte-Strom, während die readFields-Methode die Daten aus einem Byte-Strom deserialisiert. Beide Methoden werden von der Writable-Schnittstelle benötigt.
Anschließend müssen Sie die Java-Klassen mit den folgenden Befehlen kompilieren:
## Kompilieren Sie die Java-Klassen
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
Implementierung des Mappers und Reducers
In diesem Schritt werden wir eine Mapper- und eine Reducer-Klasse erstellen, um die Buchdaten mit dem MapReduce-Paradigma zu verarbeiten.
Benutzerdefinierter BookMapper
Zunächst erstellen Sie eine neue Java-Datei mit dem Namen BookMapper.java im Verzeichnis /home/hadoop mit dem folgenden Inhalt:
import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
// BookMapper erweitert die Mapper-Klasse, um textuelle Eingabedateien zu verarbeiten
// Eingabeschlüssel-Wert-Paare sind LongWritable (Zeilennummer) und Text (Zeileninhalt)
// Ausgabeschlüssel-Wert-Paare sind Text (Autorennamen) und Book (Buchdetails)
public class BookMapper extends Mapper<LongWritable, Text, Text, Book> {
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
// Teilen Sie die Eingabezeile durch Komma auf
String[] bookData = value.toString().split(",");
// Extrahieren Sie Titel, Autor und Jahr aus der Eingabezeile
String title = bookData[0];
String author = bookData[1];
int year = Integer.parseInt(bookData[2]);
// Schreiben Sie den Autor und die Buchdetails in den Kontext
context.write(new Text(author), new Book(title, author, year));
}
}
Diese BookMapper-Klasse nimmt eine Zeile Eingabedaten im Format "title,author,year" entgegen und emittiert ein Schlüssel-Wert-Paar mit dem Autor als Schlüssel und einem Book-Objekt als Wert.
Benutzerdefinierter BookReducer
Als nächstes erstellen Sie eine neue Java-Datei mit dem Namen BookReducer.java im Verzeichnis /home/hadoop mit dem folgenden Inhalt:
import java.io.IOException;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
// BookReducer erweitert die Reducer-Klasse, um Buchdetails nach Autor zu aggregieren
// Eingabeschlüssel-Wert-Paare sind Text (Autorennamen) und Book (Buchdetails)
// Ausgabeschlüssel-Wert-Paare sind Text (Autorennamen) und Book (aggregierte Buchdetails)
public class BookReducer extends Reducer<Text, Book, Text, Book> {
@Override
protected void reduce(Text key, Iterable<Book> values, Context context) throws IOException, InterruptedException {
// Iterieren Sie durch die Bücher für denselben Autor und schreiben Sie jedes Buch in den Kontext
for (Book book : values) {
context.write(key, book);
}
}
}
Diese BookReducer-Klasse emittiert einfach die Eingabeschlüssel-Wert-Paare unverändert, was effektiv die Bücher nach Autor gruppiert.
Kompilieren der Dateien
Schließlich müssen Sie die Java-Klassen mit den folgenden Befehlen kompilieren:
## Kompilieren Sie die Java-Klassen
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
Ausführen des MapReduce-Jobs
In diesem Schritt werden wir eine Driver-Klasse erstellen, um den MapReduce-Job auszuführen und die Buchdaten zu verarbeiten.
Benutzerdefinierter BookDriver
Zunächst erstellen Sie eine neue Java-Datei mit dem Namen BookDriver.java im Verzeichnis /home/hadoop mit dem folgenden Inhalt:
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 konfiguriert und übermittelt den MapReduce-Job
public class BookDriver {
public static void main(String[] args) throws Exception {
// Erstellen Sie eine neue Hadoop-Job-Konfiguration
Configuration conf = new Configuration();
// Instanziieren Sie ein Job-Objekt mit der Job-Konfiguration
Job job = Job.getInstance(conf, "Book Processing");
// Geben Sie die Jar-Datei des Jobs anhand der Klasse an
job.setJarByClass(BookDriver.class);
// Legen Sie die Mapper-Klasse fest
job.setMapperClass(BookMapper.class);
// Legen Sie die Reducer-Klasse fest
job.setReducerClass(BookReducer.class);
// Legen Sie die Ausgabeschlüsselklasse für den Job fest
job.setOutputKeyClass(Text.class);
// Legen Sie die Ausgabewertklasse für den Job fest
job.setOutputValueClass(Book.class);
// Legen Sie den Eingabepfad des Jobs fest
FileInputFormat.addInputPath(job, new Path(args[0]));
// Legen Sie den Ausgabepfad des Jobs fest
FileOutputFormat.setOutputPath(job, new Path(args[1]));
// Beenden Sie mit dem Abschlussstatus des Jobs
System.exit(job.waitForCompletion(true)? 0 : 1);
}
}
Diese BookDriver-Klasse konfiguriert und führt den MapReduce-Job aus. Sie konfiguriert den Job mit den BookMapper- und BookReducer-Klassen, legt die Eingabe- und Ausgabepfade fest und wartet auf die Fertigstellung des Jobs.
Ausführen des Jobs
Um den MapReduce-Job auszuführen, müssen Sie die Java-Klassen kompilieren und eine JAR-Datei erstellen. Sie können die folgenden Befehle verwenden:
## Kompilieren Sie die Java-Klassen
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
## Erstellen Sie eine JAR-Datei
jar -cvf book.jar *.class
Als nächstes müssen Sie ein Eingabeverzeichnis erstellen und einige Beispielbuchdaten hineinkopieren. Sie können die folgenden Befehle verwenden:
## Erstellen Sie ein Eingabeverzeichnis
hdfs dfs -mkdir /input
## Kopieren Sie Beispiel-Daten in das Eingabeverzeichnis
hdfs dfs -put./data.txt /input
Schließlich können Sie den MapReduce-Job mit dem folgenden Befehl ausführen:
hadoop jar book.jar BookDriver /input /output
Dieser Befehl wird die BookDriver-Klasse ausführen, die Eingabedaten aus /input verwenden und die Ergebnisse in /output ausgeben. Sie können das Ergebnis mit dem folgenden Befehl anzeigen.
hdfs dfs -cat /output/part-r-00000
Zusammenfassung
Herzlichen Glückwunsch! Sie haben die Serialisierung in Hadoop MapReduce erfolgreich beherrscht und dabei die Erstellung benutzerdefinierter Writable-Klassen bewältigt. In einem Szenario, in dem der Leiter der Bibliothek einer magischen Akademie eine umfangreiche Buchsammlung verwaltet, haben Sie eine Book-Klasse erstellt, die die Writable-Schnittstelle implementiert, um eine nahtlose Daten-Serialisierung und -Deserialisierung zu ermöglichen. Indem Sie eine BookMapper-Klasse zum Extrahieren von Buchinformationen und eine BookReducer-Klasse zum effizienten Gruppieren von Büchern nach Autor kreiert haben, haben Sie den Prozess mit einer BookDriver-Klasse orchestriert. Dies umfasste Aufgaben wie das Kompilieren von Java-Klassen, das Erstellen einer JAR-Datei und das Ausführen des Jobs auf dem Hadoop-Cluster. Im gesamten Prozess haben Sie unerschätzbare Erfahrungen in Hadoop MapReduce gewonnen und Ihre Fähigkeiten in benutzerdefinierten Writable-Klassen, Mapper- und Reducer-Klassen sowie der Orchestrierung von MapReduce-Jobs für große Datenverarbeitungstasks verfeinert.



