一個簡單的求每一年溫度最大值的程序。java
準備兩個名爲data1.txt及data2.txt的文件,用於作爲計算的輸入數據,將其放於/home/fenglibin/java/data目錄下:node
data1.txtapache |
data2.txtubuntu |
1999 10api 1999 20app 1999 25ide 2000 21oop 2000 22測試 2000 18spa 2000 40 2001 45 2001 65 2002 90 2002 89 2002 70 2003 40 2003 80 |
1999 40 1999 10 1999 25 2000 51 2000 22 2000 18 2000 40 2001 95 2001 65 2002 90 2002 19 2002 70 2003 100 2003 80 |
每行有兩列,分別表示年份和溫度。
該代碼來自於《Hadoop權威指南(第二版)》,以下:
package hadoop;
import java.io.IOException;
import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; 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;
public class MaxTemperature {
static class MaxTemperatureMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
@Override public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String line = value.toString(); if (line == null || line.trim().equals("")) { return; } String[] arr = line.split(" "); String year = arr[0]; int airTemperature = Integer.parseInt(arr[1]); context.write(new Text(year), new IntWritable(airTemperature)); } }
static class MaxTemperatureReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
@Override public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int maxValue = Integer.MIN_VALUE; for (IntWritable value : values) { maxValue = Math.max(maxValue, value.get()); } context.write(key, new IntWritable(maxValue)); } }
public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException { Job job = new Job(); job.setJarByClass(MaxTemperature.class); FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); job.setMapperClass(MaxTemperatureMapper.class); job.setReducerClass(MaxTemperatureReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class);
System.exit(job.waitForCompletion(true) ? 0 : 1); } } |
javac -cp $HADOOP_HOME/hadoop-core-1.2.1.jar hadoop/MaxTemperature.java |
執行的方式有兩種,直接經過java命令和$HADOOP_HOME/bin/hadoop命令,不過不一樣的執行方式有必定的區別。
有以下特色:
1)、指定本地的輸入文件;
2)、將結果輸出到本地;
3)、須要指定依賴的一長串classpath;
4)、只須要啓動map/reduce便可,不須要啓動namenode及datanode;
5)、須要在class所在目錄執行,於是不須要指定HADOOP_CLASSPATH。
執行以下:
java -Xmx256m -Xms256m -XX:PermSize=128m -cp $HADOOP_HOME:.:$HADOOP_HOME/hadoop-core-1.2.1.jar:$HADOOP_HOME/hadoop-tools-1.2.1.jar:$HADOOP_HOME/hadoop-ant-1.2.1.jar:$HADOOP_HOME/hadoop-client-1.2.1.jar:$HADOOP_HOME/hadoop-minicluster-1.2.1.jar:$HADOOP_HOME/lib/commons-logging-1.1.1.jar:$HADOOP_HOME/lib/commons-logging-api-1.0.4.jar:$HADOOP_HOME/lib/commons-configuration-1.6.jar:$HADOOP_HOME/lib/commons-lang-2.4.jar:$HADOOP_HOME/lib/jackson-core-asl-1.8.8.jar:$HADOOP_HOME/lib/jackson-mapper-asl-1.8.8.jar:$HADOOP_HOME/lib/commons-httpclient-3.0.1.jar hadoop/MaxTemperature /home/fenglibin/java/data/ /home/fenglibin/java/result/ |
有以下特色:
1)、輸入文件必須放到hdfs上;
2)、輸出結果在hdfs上;
3)、須要設置HADOOP_CLASSPATH,但不是絕對;
4)、須要將class文件打成jar包。
HADOOP_CLASSPATH是用於添加用戶的jar,hadoop在執行的時候會將其追加到hadoop自己的classpath中。Hadoop在啓動的時候,會將$HADOOP_HOME/lib目錄下面的jar所有加到classpath中,若是想偷懶不設置HADOOP_CLASSPATH,能夠將你的jar包放到$HADOOP_HOME/lib中。
4.2.1、將class文件打成jar包
首先須要建立一個mainfest.mf,放在與要打包的class相同的目錄中,裏面寫上內容:
Main-Class: hadoop.MaxTemperature
|
而後經過以下命令進行打包:
jar cvfm maxTemperature.jar mainfest.mf -c hadoop/ |
4.2.2、設置HADOOP_CLASSPATH
如此時maxTe mperature.jar放在/home/fenglibin/java目錄下,此時設置HADOOP_CLASSPATH以下:
export HADOOP_CLASSPATH=/home/fenglibin/java/maxTemperature.jar |
4.2.3、拷貝本地文件到HDFS
hdfs -copyFromLocal data ~/java |
注:hdfs是我本地的「hadoop fs」的alias,目錄「~/java」是hdfs中的目錄。
查看是否拷貝成功:
hdfs -ls ~/java |
結果以下:
fenglibin@ubuntu1110 :~/java$ hdfs -ls ~/java Warning: $HADOOP_HOME is deprecated.
Found 1 items drwxr-xr-x - fenglibin supergroup 0 2013-12-25 14:33 /home/fenglibin/java/data
|
文件已經存在,表示拷貝成功。
4.2.4、執行
Jar的mainfest.mf中標識了Main-Class是hadoop/MaxTemperature是主類,於是咱們能夠有兩種執行方式,直接執行類hadoop/MaxTemperature或者直接執行jar。
1)、直接執行類hadoop/MaxTemperature
hadoop hadoop/MaxTemperature ~/java/data ~/java/result1 |
2)、直接執行jar包
hadoop jar /home/fenglibin/java/maxTemperature.jar ~/java/data ~/java/result2 |
雖然這種方式是執行jar包,其實也是調用類hadoop/MaxTemperature執行,只是入口不同而已。
4.2.5 查看結果
以上兩種方式執行的計算結果是相同的,結果文件有一些不一樣,結果的存放位置不一樣,經過JAVA直接執行的結果是存放在本地的,經過Hadoop執行的結果是放到Hdfs上的。
下面的截圖是經過JAVA執行後,在/home/fenglibin/java/result/下面生成四個文件:
其中兩個.crc文件是隱藏,是用於CRC校驗的,咱們不須要關心;
_SUCCESS是一個空文件,只是用於表示當前操做執行成功;
part_r_00000裏面存放的就是咱們每一年最大值的輸出結果,內容以下:
下面的截圖是經過Hadoop執行,在~/java/result目錄下面的結果:
part_r_00000裏面的內容和經過JAVA執行結果是同樣的,這裏就不貼圖了。經過Hadoop命令執行,裏面多了一個_logs目錄,它裏面存放了本次用於執行的jar文件以及本次執行Hadoop用到的配置信息文件「*_conf.xml」,這個配置文件須要重點關注一下,由於這個文件裏面包含了本次計算執行所須要的全部配置信息,如下爲本次執行事後的配置文件:
注:後面補上