整個Hadoop是基於Java開發的,所以要開發Hadoop相應的程序就得用JAVA。在linux下開發JAVA還數eclipse方便。
進入官網:http://eclipse.org/downloads/。
找到相應的版本進行下載,我這裏用的是eclipse-SDK-3.7.1-linux-gtk版本。
2、解壓
下載下來一般是tar.gz文件,運行:
$tar -zxvf eclipse-SDK-3.7.1-linux-gtk.tar.gz -c ~/Tool
這裏Tool是需要解壓的目錄。
解完後,在tool下,就可以看到eclipse文件夾。
運行:
$~/Tool/eclipse/eclipse
每次運行時,輸入命令行比較麻煩,最好能創建在左側快捷菜單上。
$sudo gedit /usr/share/applications/eclipse.desktop
1)啓動文本編譯器,並創建文件,添加以下內容:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
[Desktop
Entry] Version= 1.0 Encoding=UTF- 8 Name=Eclipse3. 7.1 Exec=eclipse TryExec=eclipse Comment=Eclipse3. 7.1 ,EclipseSDK Exec=/usr/zjf/Tool/eclipse/eclipse Icon=/usr/
zjf/Tool/eclipse/icon.xpm Terminal= false Type=Application Categories=Application;Development; [注意上面的路徑] |
2)創建啓動器
1
2
3
4
5
6
|
sudo
gedit /usr/bin/eclipse 添加如下內容 #!/bin/sh export
MOZILLA_FIVE_HOME= "/usr/lib/mozilla/" export
ECLIPSE_HOME= "/usr/local/eclipse" $ECLIPSE_HOME/eclipse
$* |
1
|
sudo
chmod +x /usr/bin/eclipse |
4)在開始菜單中輸入eclipse:
就會看到軟件圖標,然後將其拖到左側工具條中即可。
直接在網上搜:hadoop-0.20.2-eclipse-plugin.jar
https://issues.apache.org/jira/secure/attachment/12460491/hadoop-eclipse-plugin-0.20.3-SNAPSHOT.jar
下載後,將jar包放在eclipse安裝目錄下的plugins文件夾下。然後啓動eclipse
第一次啓動eclpse後,會讓我們設定一個工作目錄,即以後建的項目都在這個工作目錄下。
進入後,在菜單window->Rreferences下打開設置:
點擊browse選擇hadoop的源碼下的Build目錄,然後點OK
打開Window->View View->Other 選擇Map/Reduce Tools,單擊Map/Reduce Locations,會打開一個View,
添加Hadoop Loacation,其中Host和Port的內容跟據conf/hadoop-site.xml的配置填寫,UserName 是用戶名,如
在配置完後,在Project Explorer中就可以瀏覽到DFS中的文件,一級級展開,可以看到之前我們上傳的in文件夾,以及當是存放的2個txt文件,同時看到一個在計算完後的out文件夾。
現在我們要準備自己寫個Hadoop 程序了,所以我們要把這個out文件夾刪除,有兩種方式,一是可以在這樹上,執行右健刪除。 二是可以用命令行:
$bin/hadoop fs -rmr out
用$bin/hadoop fs -ls 查看
環境搭建好了,之前運行Hadoop時,直接用了examples中的示例程序跑了下,現在可以自己來寫這個HelloWorld了。
在eclipse菜單下 new Project 可以看到,裏面增加了Map/Reduce選項:
選中,點下一步:
輸入項目名稱後,繼續(next), 再點Finish
然後在Project Explorer中就可以看到該項目了,展開,src發現裏面啥也沒有,於是右健菜單,新建類(new->new class):
然後點擊Finish,就可以看到創建了一個java類了:
-----------------------------------------------
以上爲轉載,結合自己試驗寫了如下:
-----------------------------------------------
1、 新建hadoop工程
2、新建.class 文件
隨便找的一個單詞計數的程序如下
package helloword;
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.mapred.JobConf;
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 {
/**
* MapReduceBase類:實現了Mapper和Reducer接口的基類(其中的方法只是實現接口,而未作任何事情)
* Mapper接口:
* WritableComparable接口:實現WritableComparable的類可以相互比較。所有被用作key的類應該實現此接口。
* Reporter 則可用於報告整個應用的運行進度,本例中未使用。
*
*/
public static class TokenizerMapper
extends Mapper<Object, Text, Text, IntWritable>{
/**
* LongWritable, IntWritable, Text 均是 Hadoop 中實現的用於封裝 Java 數據類型的類,這些類實現了WritableComparable接口,
* 都能夠被串行化從而便於在分佈式環境中進行數據交換,你可以將它們分別視爲long,int,String 的替代品。
*/
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();//Text 實現了BinaryComparable類可以作爲key值
/**
* Mapper接口中的map方法:
* void map(K1 key, V1 value, OutputCollector<K2,V2> output, Reporter reporter)
* 映射一個單個的輸入k/v對到一箇中間的k/v對
* 輸出對不需要和輸入對是相同的類型,輸入對可以映射到0個或多個輸出對。
* OutputCollector接口:收集Mapper和Reducer輸出的<k,v>對。
* OutputCollector接口的collect(k, v)方法:增加一個(k,v)對到output
*/
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
/**
* 原始數據:
* c++ java hello
world java hello
you me too
map階段,數據如下形式作爲map的輸入值:key爲偏移量
0 c++ java hello
16 world java hello
34 you me too
*/
/**
* 以下解析鍵值對
* 解析後以鍵值對格式形成輸出數據
* 格式如下:前者是鍵排好序的,後者數字是值
* c++ 1
* java 1
* hello 1
* world 1
* java 1
* hello 1
* you 1
* me 1
* too 1
* 這些數據作爲reduce的輸出數據
*/
StringTokenizer itr = new StringTokenizer(value.toString());//得到什麼值
System.out.println("value什麼東西 : "+value.toString());
System.out.println("key什麼東西 : "+key.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();
/**
* reduce過程是對輸入數據解析形成如下格式數據:
* (c++ [1])
* (java [1,1])
* (hello [1,1])
* (world [1])
* (you [1])
* (me [1])
* (you [1])
* 供接下來的實現的reduce程序分析數據數據
*
*/
public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int sum = 0;
/**
* 自己的實現的reduce方法分析輸入數據
* 形成數據格式如下並存儲
* c++ 1
* hello 2
* java 2
* me 1
* too 1
* world 1
* you 1
*
*/
for (IntWritable val : values) {
sum += val.get();
}
result.set(sum);
context.write(key, result);
}
}
public static void main(String[] args) throws Exception {
/**
* JobConf:map/reduce的job配置類,向hadoop框架描述map-reduce執行的工作
* 構造方法:JobConf()、JobConf(Class exampleClass)、JobConf(Configuration conf)等
*/
Configuration conf = new Configuration();
String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
//這裏需要配置參數即輸入和輸出的HDFS的文件路徑
if (otherArgs.length != 2) {
System.err.println("Usage: wordcount <in> <out>");
System.exit(2);
}
// JobConf conf1 = new JobConf(WordCount.class);
Job job = new Job(conf, "word count");//Job(Configuration conf, String jobName) 設置job名稱和
job.setJarByClass(WordCount.class);
job.setMapperClass(TokenizerMapper.class); //爲job設置Mapper類
job.setCombinerClass(IntSumReducer.class); //爲job設置Combiner類
job.setReducerClass(IntSumReducer.class); //爲job設置Reduce類
job.setOutputKeyClass(Text.class); //設置輸出key的類型
job.setOutputValueClass(IntWritable.class);// 設置輸出value的類型
FileInputFormat.addInputPath(job, new Path(otherArgs[0])); //爲map-reduce任務設置InputFormat實現類 設置輸入路徑
FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));//爲map-reduce任務設置OutputFormat實現類 設置輸出路徑
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
3、工程上右鍵 run as Run configuration(配置)
看看hdfs中的文件結構路徑是咋放的:
對應的參數配置寫法:
對 VM argument 進行補充配置可以有效的消除 運行過程中的警告信息~~~
4、看結果
調試結果
計數結果:
datanode上的結果