Java MapReduce-programok fejlesztése az Apache Hadoophoz a HDInsighton

Megtudhatja, hogyan hozhat létre Java-alapú MapReduce-alkalmazást az Apache Maven használatával, majd futtathatja az Apache Hadooppal az Azure HDInsightban.

Előfeltételek

A fejlesztési környezet konfigurálása

A cikkhez használt környezet egy Windows 10 futtató számítógép volt. A parancsok egy parancssorban lettek végrehajtva, és a különböző fájlok a Jegyzettömbben lettek szerkesztve. Ennek megfelelően módosítsa a környezetet.

A parancssorból írja be az alábbi parancsokat egy munkakörnyezet létrehozásához:

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

Maven-projekt létrehozása

  1. Adja meg a következő parancsot egy Wordcountjava nevű Maven-projekt létrehozásához:

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

    Ez a parancs létrehoz egy könyvtárat a paraméter által megadott névvel (ebben a artifactID példában wordcountjava ).) Ez a könyvtár a következő elemeket tartalmazza:

    • pom.xml – A projekt létrehozásához használt információkat és konfigurációs adatokat tartalmazó projektobjektum-modell (POM ).
    • src\main\java\org\apache\hadoop\examples: Az alkalmazás kódját tartalmazza.
    • src\test\java\org\apache\hadoop\examples: Az alkalmazás tesztjeit tartalmazza.
  2. Távolítsa el a létrehozott példakódot. Törölje a létrehozott teszt- és alkalmazásfájlokat AppTest.java, és App.java adja meg az alábbi parancsokat:

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

A Projektobjektum-modell frissítése

A pom.xml fájl teljes körű ismertetését lásd: https://maven.apache.org/pom.html. Nyissa meg pom.xml az alábbi parancs beírásával:

notepad pom.xml

Függőségek hozzáadása

A pom.xmlfájlban adja hozzá a következő szöveget a <dependencies> szakaszhoz:

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

Ez definiálja a szükséges kódtárakat (amelyek az artifactId-ben <>szerepelnek) egy adott verzióval (a verzióban<>). Fordításkor ezek a függőségek az alapértelmezett Maven-adattárból töltődnek le. A Maven-adattár keresésével továbbiak is megtekinthetők.

A <scope>provided</scope> rendszer azt mondja a Mavennek, hogy ezeket a függőségeket nem szabad az alkalmazással együtt csomagolni, mivel a HDInsight-fürt futásidőben biztosítja őket.

Fontos

A használt verziónak meg kell egyeznie a fürtön található Hadoop verziójával. A verziókról további információt a HDInsight-összetevő verziószámozási dokumentumában talál.

Buildelési konfiguráció

A Maven beépülő moduljai lehetővé teszik a projekt buildelési szakaszainak testreszabását. Ez a szakasz beépülő modulok, erőforrások és más buildkonfigurációs beállítások hozzáadására szolgál.

Adja hozzá a következő kódot a pom.xml fájlhoz, majd mentse és zárja be a fájlt. Ennek a szövegnek a <project>...</project> fájl címkéiben kell lennie, például a és </project>a között</dependencies>.

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

Ez a szakasz az Apache Maven Fordító beépülő modult és az Apache Maven Shade beépülő modult konfigurálja. A fordító beépülő modul a topológia fordítására szolgál. Az árnyékoló beépülő modul a Maven által létrehozott JAR-csomag licenc-duplikációjának megakadályozására szolgál. Ez a beépülő modul a HDInsight-fürt futásidejű "duplikált licencfájlok" hibájának megelőzésére szolgál. A maven-shade-plugin implementációval való ApacheLicenseResourceTransformer használata megakadályozza a hibát.

A maven-shade-plugin egy uber jar-t is létrehoz, amely tartalmazza az alkalmazás által igényelt összes függőséget.

Mentse a pom.xml fájlt.

A MapReduce alkalmazás létrehozása

  1. Új fájl létrehozásához és megnyitásához írja be az alábbi parancsot WordCount.java. Új fájl létrehozásához válassza az Igen lehetőséget a parancssorban.

    notepad src\main\java\org\apache\hadoop\examples\WordCount.java
    
  2. Ezután másolja és illessze be az alábbi Java-kódot az új fájlba. Ezután zárja be a fájlt.

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

    Figyelje meg, hogy a csomag neve és org.apache.hadoop.examples az osztály neve WordCount. Ezeket a neveket a MapReduce feladat elküldésekor használja.

Az alkalmazás létrehozása és becsomagolása

A könyvtárban wordcountjava az alábbi paranccsal hozzon létre egy JAR-fájlt, amely tartalmazza az alkalmazást:

mvn clean package

Ez a parancs megtisztítja a korábbi buildelési összetevőket, letölti a még nem telepített függőségeket, majd létrehozza és csomagolja az alkalmazást.

A parancs befejeződése után a wordcountjava/target könyvtár egy nevű wordcountjava-1.0-SNAPSHOT.jarfájlt tartalmaz.

Megjegyzés

A wordcountjava-1.0-SNAPSHOT.jar fájl egy uberjar, amely nem csak a WordCount feladatot tartalmazza, hanem a feladat futásidejű függőségeit is.

Töltse fel a JAR-t, és futtassa a feladatokat (SSH)

Az alábbi lépéseket követve scp másolja a JAR-t a HDInsight-alapú Apache HBase-fürt elsődleges átjárócsomópontjára. A ssh parancsot ezután a fürthöz való csatlakozáshoz és a példa futtatásához használja közvetlenül az átjárócsomóponton.

  1. Töltse fel a jar-t a fürtbe. Cserélje le CLUSTERNAME a elemet a HDInsight-fürt nevére, majd írja be a következő parancsot:

    scp target/wordcountjava-1.0-SNAPSHOT.jar sshuser@CLUSTERNAME-ssh.azurehdinsight.net:
    
  2. Csatlakozzon a fürthöz. Cserélje le CLUSTERNAME a elemet a HDInsight-fürt nevére, majd írja be a következő parancsot:

    ssh sshuser@CLUSTERNAME-ssh.azurehdinsight.net
    
  3. Az SSH-munkamenetben az alábbi paranccsal futtassa a MapReduce alkalmazást:

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

    Ez a parancs elindítja a WordCount MapReduce alkalmazást. A bemeneti fájl a , /example/data/gutenberg/davinci.txta kimeneti könyvtár pedig ./example/data/wordcountout A bemeneti fájl és a kimenet is a fürt alapértelmezett tárolójában van tárolva.

  4. A feladat befejezése után az alábbi paranccsal tekintheti meg az eredményeket:

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

    A szavak és a számok listáját az alábbi szöveghez hasonló értékekkel kell megkapnia:

    zeal    1
    zelus   1
    zenith  2
    

Következő lépések

Ebben a dokumentumban megtanulta, hogyan fejleszthet Java MapReduce-feladatokat. A HDInsight használatával kapcsolatos egyéb módokért tekintse meg az alábbi dokumentumokat.