Dela via


Utveckla Java MapReduce-program för Apache Hadoop på 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 skriver du in kommandona nedan för att skapa en fungerande miljö:

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 namnet som anges av parametern artifactID (wordcountjava i det här exemplet.) Den här katalogen innehåller följande objekt:

    • pom.xmlProject Object Model (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 för 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 obligatoriska bibliotek (som visas i <artifactId>) med en specifik version (listad i <version>). Vid kompileringstillfället laddas dessa beroenden ned från maven-standardlagringsplatsen. Du kan använda Maven-lagringsplatssökningen för att visa mer.

<scope>provided</scope> säger till Maven att dessa beroenden inte bör paketeras med programmet, eftersom de tillhandahålls av HDInsight-klustret vid körningstid.

Viktigt!

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

Byggkonfiguration

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

Lägg till följande kod i pom.xml filen och spara och stäng sedan filen. Den här texten måste finnas i 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 Apache Maven Compiler-plugin-programmet och Apache Maven Shade-plugin-programmet. 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 har skapats av Maven. Det här tillägget används för att undvika 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 producerar också en uber-jar som innehåller alla beroenden som programmet kräver.

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

Från katalogen wordcountjava använder du följande kommando 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 är klart innehåller katalogen wordcountjava/target en fil med namnet wordcountjava-1.0-SNAPSHOT.jar.

Anmärkning

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ör 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 WordCount MapReduce-programmet. 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 är klart 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. I följande dokument finns andra sätt att arbeta med HDInsight.