開發適用於 HDInsight 上 Apache Hadoop 的 Java MapReduce 程式
了解如何使用 Apache Maven 來建立以 Java 為基礎的 MapReduce 應用程式,然後在 Azure HDInsight 上使用 Apache Hadoop 來加以執行。
必要條件
根據 Apache 正確安裝的 Apache Maven。 Maven 是適用於 Java 專案的專案建置系統。
設定開發環境
用於本文的環境是執行 Windows 10 的電腦。 命令已在命令提示字元中執行,而且各種檔案已使用記事本進行編輯。 針對您的環境據以修改。
從命令提示字元中,輸入下列命令以建立工作環境:
IF NOT EXIST C:\HDI MKDIR C:\HDI
cd C:\HDI
建立 Maven 專案
輸入下列命令建立名為 wordcountjava 的 Maven 專案:
mvn archetype:generate -DgroupId=org.apache.hadoop.examples -DartifactId=wordcountjava -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
此命令會使用
artifactID
參數所指定的名稱 (此範例中為 wordcountjava) 來建立目錄。此目錄包含下列項目:pom.xml
- 專案物件模型 (POM),包含用來建置專案的資訊和組態詳細資料。- src\main\java\org\apache\hadoop\examples:包含應用程式程式碼。
- src\test\java\org\apache\hadoop\examples:包含應用程式的測試。
移除所產生的範例程式碼。 輸入下列命令,以刪除產生的測試和應用程式檔案
AppTest.java
及App.java
:cd wordcountjava DEL src\main\java\org\apache\hadoop\examples\App.java DEL src\test\java\org\apache\hadoop\examples\AppTest.java
更新專案物件模型
如需 pom.xml 檔案的完整參考,請參閱 https://maven.apache.org/pom.html。 輸入下列命令以開啟 pom.xml
:
notepad pom.xml
新增相依性
在 pom.xml
中,在 <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>
這會定義含有特定版本 (列於<version> 內) 的必要程式庫 (列於 <artifactId> 內)。 在編譯期間,會從預設的 Maven 儲存機制下載這些相依性。 您可以使用 Maven 儲存機制搜尋 (英文) 檢視詳細資訊。
<scope>provided</scope>
會告訴 Maven 這些相依性不應該和應用程式一起封裝,因為 HDInsight 叢集會在執行階段提供這些相依性。
重要
使用的版本應該符合您叢集上的 Hadoop 版本。 如需有關版本的詳細資訊,請參閱 HDInsight 元件版本設定文件。
組建組態
Maven 外掛程式可讓您自訂專案的建置階段。 此區段會用來新增外掛程式、資源,和其他組建組態選項。
將下列程式碼加入 pom.xml
檔案,然後儲存並關閉該檔案。 此文字必須位在檔案中的 <project>...</project>
標籤內,例如在 </dependencies>
和 </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>
此區段會設定 Apache Maven Compiler 外掛程式和 Apache Maven Shade 外掛程式。 Compiler 外掛程式用來編譯拓撲。 Shade 外掛程式用來防止以 Maven 所建置的 JAR 封裝發生授權重複。 此外掛程式是用於防止 HDInsight 叢集在執行階段發生「重複的授權檔案」錯誤。 使用 maven-shade-plugin 搭配 ApacheLicenseResourceTransformer
實作可防止此錯誤。
maven-shade-plugin 也會產生 uber jar,其中含有應用程式需要的所有相依性。
儲存pom.xml
檔案。
建立 MapReduce 應用程式
輸入下列命令以建立並開啟新的檔案
WordCount.java
。 在命令提示字元中選取 [是],以建立新的檔案。notepad src\main\java\org\apache\hadoop\examples\WordCount.java
接著複製下方的 Java 程式碼並將其貼入新的檔案中。 然後關閉檔案。
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); } }
請注意,封裝名稱是
org.apache.hadoop.examples
,而類別名稱是WordCount
。 提交 MapReduce 作業時會用到這些名稱。
建置和封裝應用程式
從 wordcountjava
目錄,使用下列命令來建置含有應用程式的 JAR 檔案:
mvn clean package
此命令會清除任何先前的組建構件、下載任何尚未安裝的相依性,然後建置並封裝應用程式。
一旦命令完成之後,wordcountjava/target
目錄就會包含名為 wordcountjava-1.0-SNAPSHOT.jar
的檔案。
注意
wordcountjava-1.0-SNAPSHOT.jar
檔案是一個 uberjar,其中不只含有 WordCount 作業,還有該作業在執行階段所需的相依性。
上傳 JAR 並執行作業 (SSH)
下列步驟使用 scp
,將 JAR 複製到 HDInsight 叢集上 Apache HBase 的主要前端節點。 接著,會使用 ssh
命令連接到該叢集並直接在前端節點上執行範例。
將 jar 上傳至叢集。 將
CLUSTERNAME
取代為 HDInsight 叢集名稱,然後輸入下列命令:scp target/wordcountjava-1.0-SNAPSHOT.jar sshuser@CLUSTERNAME-ssh.azurehdinsight.net:
連線至叢集。 將
CLUSTERNAME
取代為 HDInsight 叢集名稱,然後輸入下列命令:ssh sshuser@CLUSTERNAME-ssh.azurehdinsight.net
在 SSH 工作階段中,使用以下命令執行 MapReduce 應用程式:
yarn jar wordcountjava-1.0-SNAPSHOT.jar org.apache.hadoop.examples.WordCount /example/data/gutenberg/davinci.txt /example/data/wordcountout
此命令會啟動 WordCount MapReduce 應用程式。 輸入檔案為
/example/data/gutenberg/davinci.txt
,輸出目錄則為/example/data/wordcountout
。 輸入檔和輸出都會儲存至叢集的預設儲存體中。作業完成之後,請使用以下命令來檢視結果:
hdfs dfs -cat /example/data/wordcountout/*
您應該會收到一份單字和計數的清單,其中含有類似下列文字的值:
zeal 1 zelus 1 zenith 2
下一步
在本文件中,您已學到如何開發 Java MapReduce 工作。 請參閱下列文件,了解其他的 HDInsight 使用方式。