Entwickeln von Java MapReduce-Programmen für Apache Hadoop in HDInsight
Erfahren Sie, wie Sie Apache Maven verwenden, um eine Java-basierte MapReduce-Anwendung zu erstellen und anschließend mit Apache Hadoop in HDInsight ausführen.
Voraussetzungen
Ordnungsgemäße Installation von Apache Maven (gemäß Apache). Maven ist ein Projekterstellungssystem für Java-Projekte.
Konfigurieren der Entwicklungsumgebung
Für diesen Artikel wurde ein Computer unter Windows 10 verwendet. Die Befehle wurden an einer Eingabeaufforderung ausgeführt, und die verschiedenen Dateien wurden mit dem Windows-Editor bearbeitet. Nehmen Sie die Ihrer Umgebung entsprechenden Änderungen vor.
Geben Sie an einer Eingabeaufforderung die folgenden Befehle ein, um eine Arbeitsumgebung zu erstellen:
IF NOT EXIST C:\HDI MKDIR C:\HDI
cd C:\HDI
Erstellen eines Maven-Projekts
Geben Sie den folgenden Befehl ein, um ein Maven-Projekt mit dem Namen wordcountjava zu erstellen:
mvn archetype:generate -DgroupId=org.apache.hadoop.examples -DartifactId=wordcountjava -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
Mit diesem Befehl wird ein Verzeichnis mit dem durch den
artifactID
Parameter angegebenen Namen erstellt (in diesem Beispiel wordcountjava.) Dieses Verzeichnis enthält die folgenden Elemente:-
pom.xml
– das Projektobjektmodell (POM), das die Informationen und Konfigurationsdetails für das Erstellen des Projekts enthält. - src\main\java\org\apache\hadoop\examples: Enthält den Code Ihrer Anwendung.
- src\test\java\org\apache\hadoop\examples: Enthält Tests für Ihre Anwendung.
-
Entfernen Sie den generierten Beispielcode. Geben Sie die folgenden Befehle ein, um die generierten Test- und Anwendungsdateien (
AppTest.java
undApp.java
) zu löschen:cd wordcountjava DEL src\main\java\org\apache\hadoop\examples\App.java DEL src\test\java\org\apache\hadoop\examples\AppTest.java
Aktualisieren des Projektobjektmodells
Eine vollständige Referenz der Datei „pom.xml“ finden Sie unter https://maven.apache.org/pom.html. Geben Sie den folgenden Befehl ein, um pom.xml
zu öffnen:
notepad pom.xml
Hinzufügen von Abhängigkeiten
Fügen Sie in pom.xml
im Abschnitt <dependencies>
den folgenden Text hinzu:
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-examples</artifactId>
<version>2.7.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-common</artifactId>
<version>2.7.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.3</version>
<scope>provided</scope>
</dependency>
Damit werden die erforderlichen Bibliotheken (aufgelistet in <artifactId>) in bestimmten Versionen (aufgelistet in <version>) definiert. Beim Kompilieren werden diese Abhängigkeiten aus dem Maven-Standardrepository heruntergeladen. Sie können die Maven-Repositorysuche verwenden, um weitere Komponenten anzuzeigen.
<scope>provided</scope>
gibt für Maven an, dass diese Abhängigkeiten nicht mit der Anwendung zusammengepackt werden sollen, da sie durch den HDInsight-Cluster zur Laufzeit bereitgestellt werden.
Wichtig
Die verwendete Version sollte mit der aktuell in Ihrem Cluster vorhandenen Hadoop-Version übereinstimmen. Weitere Informationen zu Versionen finden Sie im Dokument über HDInsight-Komponenten und -Versionen.
Buildkonfiguration
Mithilfe von Maven-Plug-Ins können Sie die Buildphasen des Projekts anpassen. Dieser Abschnitt wird zum Hinzufügen von Plug-Ins, Ressourcen und anderen Optionen für die Buildkonfiguration verwendet.
Fügen Sie der Datei pom.xml
den folgenden Code hinzu, und speichern und schließen Sie die Datei. Dieser Text muss sich in der Datei innerhalb der <project>...</project>
-Tags befinden, z.B. zwischen </dependencies>
und </project>
.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer">
</transformer>
</transformers>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
In diesem Abschnitt werden auch das Apache Maven-Compiler-Plug-In und das Apache Maven-Shade-Plug-In konfiguriert. Das Compiler-Plug-In wird zum Kompilieren der Topologie verwendet. Das Shade-Plug-In wird verwendet, um die Lizenzduplizierung in dem von Maven erstellten JAR-Paket zu verhindern. Dieses Plug-In wird verwendet, um einen Fehler des Typs „Doppelte Lizenzdateien“ zur Laufzeit im HDInsight-Cluster zu vermeiden. Wenn das Maven-Shade-Plug-In mit der ApacheLicenseResourceTransformer
-Implementierung verwendet wird, wird der Fehler vermieden.
Das maven-shade-plugin generiert außerdem ein Uberjar, das alle Abhängigkeiten enthält, die in der Anwendung benötigt werden.
Speichern Sie die Datei pom.xml
.
Erstellen der MapReduce-Anwendung
Geben Sie den folgenden Befehl ein, um die neue Datei
WordCount.java
zu erstellen und zu öffnen. Wählen an der Eingabeaufforderung Ja aus, um eine neue Datei zu erstellen.notepad src\main\java\org\apache\hadoop\examples\WordCount.java
Kopieren Sie den folgenden Java-Code, und fügen Sie ihn in die neue Datei ein. Schließen Sie dann die Datei.
package org.apache.hadoop.examples; import java.io.IOException; import java.util.StringTokenizer; 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.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import org.apache.hadoop.util.GenericOptionsParser; public class WordCount { public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable>{ private final static IntWritable one = new IntWritable(1); private Text word = new Text(); public void map(Object key, Text value, Context context ) throws IOException, InterruptedException { StringTokenizer itr = new StringTokenizer(value.toString()); while (itr.hasMoreTokens()) { word.set(itr.nextToken()); context.write(word, one); } } } public static class IntSumReducer extends Reducer<Text,IntWritable,Text,IntWritable> { private IntWritable result = new IntWritable(); public void reduce(Text key, Iterable<IntWritable> values, Context context ) throws IOException, InterruptedException { int sum = 0; for (IntWritable val : values) { sum += val.get(); } result.set(sum); context.write(key, result); } } public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs(); if (otherArgs.length != 2) { System.err.println("Usage: wordcount <in> <out>"); System.exit(2); } Job job = new Job(conf, "word count"); job.setJarByClass(WordCount.class); job.setMapperClass(TokenizerMapper.class); job.setCombinerClass(IntSumReducer.class); job.setReducerClass(IntSumReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); FileInputFormat.addInputPath(job, new Path(otherArgs[0])); FileOutputFormat.setOutputPath(job, new Path(otherArgs[1])); System.exit(job.waitForCompletion(true) ? 0 : 1); } }
Beachten Sie, dass der Paketname
org.apache.hadoop.examples
und der KlassennameWordCount
ist. Diese Namen werden beim Übermitteln des MapReduce-Auftrags verwendet.
Erstellen und Packen der Anwendung
Verwenden Sie im Verzeichnis wordcountjava
den folgenden Befehl, um eine JAR-Datei zu erstellen, die die Anwendung enthält:
mvn clean package
Mit diesem Befehl werden etwaige frühere Erstellungsartefakte entfernt, alle noch nicht installierten Abhängigkeiten heruntergeladen und dann die Anwendung erstellt und gepackt.
Sobald der Befehl abgeschlossen ist, enthält das Verzeichnis wordcountjava/target
eine Datei mit dem Namen wordcountjava-1.0-SNAPSHOT.jar
.
Hinweis
Die Datei wordcountjava-1.0-SNAPSHOT.jar
ist ein Uberjar, das nicht nur den WordCount-Auftrag enthält, sondern auch Abhängigkeiten, die für den Auftrag zur Laufzeit erforderlich sind.
Hochladen der JAR-Datei und Ausführen von Aufträgen (SSH)
In den folgenden Schritten wird scp
zum Kopieren der JAR-Datei auf den primären Hauptknoten von Apache HBase im HDInsight-Cluster verwendet. Der Befehl ssh
dient dann zum Herstellen einer Verbindung mit dem Cluster und direkten Ausführen des Beispiels auf dem Hauptknoten.
Laden Sie die JAR-Datei in den Cluster hoch. Ersetzen Sie
CLUSTERNAME
durch Ihren HDInsight-Clusternamen, und geben Sie dann den folgenden Befehl ein:scp target/wordcountjava-1.0-SNAPSHOT.jar sshuser@CLUSTERNAME-ssh.azurehdinsight.net:
Verbinden mit dem Cluster Ersetzen Sie
CLUSTERNAME
durch Ihren HDInsight-Clusternamen, und geben Sie dann den folgenden Befehl ein:ssh sshuser@CLUSTERNAME-ssh.azurehdinsight.net
Verwenden Sie in der SSH-Sitzung den folgenden Befehl, um die MapReduce-Anwendung auszuführen:
yarn jar wordcountjava-1.0-SNAPSHOT.jar org.apache.hadoop.examples.WordCount /example/data/gutenberg/davinci.txt /example/data/wordcountout
Dieser Befehl startet die Anwendung WordCount MapReduce. Die Eingabedatei ist
/example/data/gutenberg/davinci.txt
, und das Ausgabeverzeichnis ist/example/data/wordcountout
. Die Eingabedatei und die Ausgabe werden im Standardspeicher für den Cluster gespeichert.Sobald der Auftrag abgeschlossen ist, verwenden Sie den folgenden Befehl zum Anzeigen der Ergebnisse:
hdfs dfs -cat /example/data/wordcountout/*
Sie sollten eine Liste von Wörtern und Zahlen mit Werten erhalten, die dem folgenden Text ähneln:
zeal 1 zelus 1 zenith 2
Nächste Schritte
In diesem Dokument haben Sie gelernt, wie ein Java MapReduce-Auftrag entwickelt wird. In den folgenden Dokumenten finden Sie andere Möglichkeiten zum Arbeiten mit HDInsight.