Hadoop Olympiade Partitionierung

HadoopHadoopBeginner
Jetzt üben

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

Im antiken griechischen Olympiade trafen sich Athleten aus dem ganzen Land, um ihre Können zu demonstrieren und an verschiedenen sportlichen Veranstaltungen teilzunehmen. Einer dieser Athleten, Alexios, hatte unermüdlich für die bevorstehenden Spiele trainiert, entschlossen, Ehre für seine Stadtstaat zu bringen.

Das Ziel war es, die Teilnehmer nach ihren Veranstaltungen in verschiedene Gruppen zu sortieren und zu organisieren, um eine faire und effiziente Konkurrenz zu gewährleisten. Mit Hunderten von Athleten, die um Ehre kämpften, war die Aufgabe, sie in ihre jeweiligen Veranstaltungen aufzuteilen, jedoch eine bedrohliche.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL hadoop(("Hadoop")) -.-> hadoop/HadoopYARNGroup(["Hadoop YARN"]) hadoop(("Hadoop")) -.-> hadoop/HadoopHiveGroup(["Hadoop Hive"]) hadoop(("Hadoop")) -.-> hadoop/HadoopMapReduceGroup(["Hadoop MapReduce"]) 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{{"Hadoop Olympiade Partitionierung"}} hadoop/shuffle_partitioner -.-> lab-288997{{"Hadoop Olympiade Partitionierung"}} hadoop/yarn_setup -.-> lab-288997{{"Hadoop Olympiade Partitionierung"}} hadoop/process -.-> lab-288997{{"Hadoop Olympiade Partitionierung"}} hadoop/udf -.-> lab-288997{{"Hadoop Olympiade Partitionierung"}} hadoop/integration -.-> lab-288997{{"Hadoop Olympiade Partitionierung"}} end

Implementiere den Mapper

In diesem Schritt erstellen wir eine Mapper-Klasse, die Eingabedaten liest und Schlüssel-Wert-Paare für den Partitioner generiert.

Ändern Sie zunächst den Benutzer in hadoop und wechseln Sie dann in das Home-Verzeichnis des hadoop-Benutzers:

su - hadoop

Erstellen Sie dann eine Java-Datei für die Mapper-Klasse:

touch /home/hadoop/OlympicMapper.java

Fügen Sie den folgenden Code zur OlympicMapper.java-Datei hinzu:

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

In der OlympicMapper-Klasse definieren wir den Eingabeschlüssel als LongWritable (repräsentiert die Zeilenverschiebung) und den Eingabewert als Text (repräsentiert eine Zeile aus der Eingabedatei). Der Ausgabeschlüssel ist ein Text-Objekt, das das Ereignis repräsentiert, und der Ausgabewert ist ein Text-Objekt, das den Namen des Athleten repräsentiert.

Die map-Methode teilt jede Zeile der Eingabedaten durch das Komma als Trennzeichen auf, extrahiert den Namen des Athleten und das Ereignis und emittiert ein Schlüssel-Wert-Paar mit dem Ereignis als Schlüssel und dem Namen des Athleten als Wert.

Implementiere den Partitioner

In diesem Schritt erstellen wir eine benutzerdefinierte Partitioner-Klasse, die die Schlüssel-Wert-Paare basierend auf dem Ereignis aufteilt.

Erstellen Sie zunächst eine Java-Datei für die Partitioner-Klasse:

touch /home/hadoop/OlympicPartitioner.java

Fügen Sie dann den folgenden Code zur OlympicPartitioner.java-Datei hinzu:

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

Die OlympicPartitioner-Klasse erweitert die von Hadoop bereitgestellte Partitioner-Klasse. Sie überschreibt die getPartition-Methode, die den Schlüssel, den Wert und die Anzahl der Partitionen als Eingabe nimmt.

Die getPartition-Methode berechnet einen Hash-Code für das Ereignis (Schlüssel) und gibt die Partitionnummer zurück, indem der absolute Wert des Hash-Codes modulo der Anzahl der Partitionen genommen wird. Dadurch wird sichergestellt, dass alle Datensätze mit demselben Ereignis an die gleiche Partition gesendet werden, um von der Reduzierfunktion verarbeitet zu werden.

Implementiere den Reducer

In diesem Schritt erstellen wir eine Reducer-Klasse, die die partitionierten Daten verarbeitet und das endgültige Ergebnis generiert.

Erstellen Sie zunächst eine Java-Datei für die Reducer-Klasse:

touch /home/hadoop/OlympicReducer.java

Fügen Sie dann den folgenden Code zur OlympicReducer.java-Datei hinzu:

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

Die OlympicReducer-Klasse erweitert die von Hadoop bereitgestellte Reducer-Klasse. Sie definiert den Eingabeschlüssel als Text (repräsentiert das Ereignis), den Eingabewert als Text (repräsentiert den Namen des Athleten) und die Ausgabeschlüssel- und -werte als Text-Objekte.

Die reduce-Methode wird für jeden eindeutigen Ereignisschlüssel aufgerufen, zusammen mit einem Iterator über die Namen der Athleten, die mit diesem Ereignis assoziiert sind. Sie baut eine komma-getrennte Liste von Athleten für jedes Ereignis auf und emittiert ein Schlüssel-Wert-Paar mit dem Ereignis als Schlüssel und der Liste der Athleten als Wert.

Schreibe den Treiber

In diesem Schritt erstellen wir eine Treiber-Klasse, die die Mapper-, Partitioner- und Reducer-Klassen zusammenbindet und den MapReduce-Job ausführt.

Erstellen Sie zunächst eine Java-Datei für die Treiber-Klasse:

touch /home/hadoop/OlympicDriver.java

Fügen Sie dann den folgenden Code zur OlympicDriver.java-Datei hinzu:

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

Die OlympicDriver-Klasse ist der Einstiegspunkt für den MapReduce-Job. Sie konfiguriert die Job-Konfiguration, gibt die Mapper-, Partitioner- und Reducer-Klassen an und konfiguriert die Eingangs- und Ausgangspfade.

In der main-Methode erstellen wir ein neues Configuration-Objekt und eine Job-Instanz mit dem Job-Namen "Olympic Partitioner". Wir setzen die Mapper-, Partitioner- und Reducer-Klassen mit den entsprechenden Setter-Methoden.

Wir setzen auch die Ausgabeschlüssel- und -wertklassen auf Text. Die Eingangs- und Ausgangspfade werden mithilfe von Befehlszeilenargumenten, die an den Treiber übergeben werden, angegeben.

Schließlich rufen wir die waitForCompletion-Methode auf der Job-Instanz auf, um den MapReduce-Job auszuführen und mit einem entsprechenden Statuscode zu beenden (0 für Erfolg, 1 für Fehler).

Um den Job auszuführen, müssen Sie die Java-Klassen kompilieren und eine Jar-Datei erstellen. Anschließend können Sie die Jar-Datei mit dem folgenden Befehl ausführen:

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

Schließlich können wir die Ergebnisse überprüfen, indem wir folgenden Befehl ausführen:

hadoop fs -cat /output/*

Beispielausgabe:

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

Zusammenfassung

In diesem Lab haben wir das Konzept des Hadoop Shuffle Partitioner durch das Entwerfen eines Szenarios untersucht, das von den antiken griechischen Olympischen Spielen inspiriert wurde. Wir haben eine Mapper-Klasse implementiert, um Eingabedaten zu lesen und Schlüssel-Wert-Paare zu generieren, eine benutzerdefinierte Partitioner-Klasse, um die Daten basierend auf dem Ereignis zu partitionieren, und eine Reducer-Klasse, um die partitionierten Daten zu verarbeiten und das endgültige Ergebnis zu generieren.

Durch dieses Lab habe ich praktische Erfahrungen mit dem MapReduce-Programmiermodell gewonnen und gelernt, wie ich die Partitioner-Klasse nutzen kann, um Daten effizient über Partitionen zu verteilen. Das Szenario der antiken griechischen Olympischen Spiele bietet einen ansprechenden Kontext, um die praktischen Anwendungen des Shuffle Partitioner in einem realen Umfeld zu verstehen.