Utveckla Java MapReduce-program för Apache Hadoop i HDInsight

Lär dig hur du använder Apache Maven för att skapa ett Java-baserat MapReduce-program och kör det sedan med Apache Hadoop i Azure HDInsight.

Förutsättningar

Konfigurera utvecklingsmiljön

Miljön som används för den här artikeln var en dator som kör Windows 10. Kommandona kördes i en kommandotolk och de olika filerna redigerades med Anteckningar. Ändra i enlighet med detta för din miljö.

Från en kommandotolk anger du kommandona nedan för att skapa en arbetsmiljö:

IF NOT EXIST C:\HDI MKDIR C:\HDI
cd C:\HDI

Skapa ett Maven-projekt

  1. Ange följande kommando för att skapa ett Maven-projekt med namnet wordcountjava:

    mvn archetype:generate -DgroupId=org.apache.hadoop.examples -DartifactId=wordcountjava -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    

    Det här kommandot skapar en katalog med det namn som anges av parametern artifactID (wordcountjava i det här exemplet.) Den här katalogen innehåller följande objekt:

    • pom.xmlProjektobjektmodellen (POM) som innehåller information och konfigurationsinformation som används för att skapa projektet.
    • src\main\java\org\apache\hadoop\examples: Innehåller programkoden.
    • src\test\java\org\apache\hadoop\examples: Innehåller tester för ditt program.
  2. Ta bort den genererade exempelkoden. Ta bort de genererade test- och programfilerna AppTest.javaoch App.java genom att ange kommandona nedan:

    cd wordcountjava
    DEL src\main\java\org\apache\hadoop\examples\App.java
    DEL src\test\java\org\apache\hadoop\examples\AppTest.java
    

Uppdatera projektobjektmodellen

En fullständig referens till filen pom.xml finns i https://maven.apache.org/pom.html. Öppna pom.xml genom att ange kommandot nedan:

notepad pom.xml

Lägga till beroenden

I pom.xmllägger du till följande text i avsnittet <dependencies> :

<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>

Detta definierar nödvändiga bibliotek (visas i <artifactId>) med en specifik version (listad i <version>). Vid kompileringstillfället laddas dessa beroenden ned från standardlagringsplatsen för Maven. Du kan använda Maven-lagringsplatsens sökning för att visa mer.

<scope>provided</scope> talar om för Maven att dessa beroenden inte ska paketeras med programmet, eftersom de tillhandahålls av HDInsight-klustret vid körning.

Viktigt

Den version som används ska matcha den version av Hadoop som finns i klustret. Mer information om versioner finns i dokumentet om versionshantering av HDInsight-komponenter .

Skapa konfiguration

Med Maven-plugin-program kan du anpassa byggfaserna i projektet. Det här avsnittet används för att lägga till plugin-program, resurser och andra konfigurationsalternativ för kompilering.

Lägg till följande kod i pom.xml filen och spara och stäng sedan filen. Den här texten måste finnas inuti taggarna <project>...</project> i filen, till exempel mellan </dependencies> och </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>

Det här avsnittet konfigurerar Plugin-programmet Apache Maven Compiler och Plugin-programmet Apache Maven Shade. Plugin-programmet för kompileraren används för att kompilera topologin. Plugin-programmet shade används för att förhindra licensduplicering i JAR-paketet som skapats av Maven. Det här plugin-programmet används för att förhindra felet "duplicerade licensfiler" vid körning i HDInsight-klustret. Om du använder maven-shade-plugin med implementeringen ApacheLicenseResourceTransformer förhindras felet.

Maven-shade-plugin-programmet skapar också en uber-jar-fil som innehåller alla beroenden som krävs av programmet.

Spara filen pom.xml.

Skapa MapReduce-programmet

  1. Ange kommandot nedan för att skapa och öppna en ny fil WordCount.java. Välj Ja i prompten för att skapa en ny fil.

    notepad src\main\java\org\apache\hadoop\examples\WordCount.java
    
  2. Kopiera och klistra sedan in Java-koden nedan i den nya filen. Stäng sedan filen.

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

    Observera att paketnamnet är org.apache.hadoop.examples och att klassnamnet är WordCount. Du använder dessa namn när du skickar MapReduce-jobbet.

Skapa och paketera programmet

Använd följande kommando från wordcountjava katalogen för att skapa en JAR-fil som innehåller programmet:

mvn clean package

Det här kommandot rensar alla tidigare byggartefakter, laddar ned eventuella beroenden som inte redan har installerats och skapar och paketar sedan programmet.

När kommandot har slutförts wordcountjava/target innehåller katalogen en fil med namnet wordcountjava-1.0-SNAPSHOT.jar.

Anteckning

Filen wordcountjava-1.0-SNAPSHOT.jar är en uberjar som inte bara innehåller WordCount-jobbet, utan även beroenden som jobbet kräver vid körning.

Ladda upp JAR och köra jobb (SSH)

Följande steg använder scp för att kopiera JAR-filen till den primära huvudnoden i Apache HBase i HDInsight-klustret. Kommandot ssh används sedan för att ansluta till klustret och köra exemplet direkt på huvudnoden.

  1. Ladda upp jar-filen till klustret. Ersätt CLUSTERNAME med ditt HDInsight-klusternamn och ange sedan följande kommando:

    scp target/wordcountjava-1.0-SNAPSHOT.jar sshuser@CLUSTERNAME-ssh.azurehdinsight.net:
    
  2. Anslut till klustret. Ersätt CLUSTERNAME med ditt HDInsight-klusternamn och ange sedan följande kommando:

    ssh sshuser@CLUSTERNAME-ssh.azurehdinsight.net
    
  3. Från SSH-sessionen använder du följande kommando för att köra MapReduce-programmet:

    yarn jar wordcountjava-1.0-SNAPSHOT.jar org.apache.hadoop.examples.WordCount /example/data/gutenberg/davinci.txt /example/data/wordcountout
    

    Det här kommandot startar Programmet WordCount MapReduce. Indatafilen är /example/data/gutenberg/davinci.txtoch utdatakatalogen är /example/data/wordcountout. Både indatafilen och utdata lagras i standardlagringen för klustret.

  4. När jobbet har slutförts använder du följande kommando för att visa resultatet:

    hdfs dfs -cat /example/data/wordcountout/*
    

    Du bör få en lista med ord och antal, med värden som liknar följande text:

    zeal    1
    zelus   1
    zenith  2
    

Nästa steg

I det här dokumentet har du lärt dig hur du utvecklar ett Java MapReduce-jobb. Se följande dokument för andra sätt att arbeta med HDInsight.