Hadoop學習筆記(4)
——搭建開發環境及編寫Hello World
整個Hadoop是基於Java開發的,所以要開發Hadoop相應的程序就得用JAVA。在linux下開發JAVA還數eclipse方便。
-
下載
進入官網:http://eclipse.org/downloads/。
找到相應的版本進行下載,我這里用的是eclipse-SDK-3.7.1-linux-gtk版本。
-
解壓
下載下來一般是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.啟動文本編譯器,並創建文件,添加以下內容:
[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.創建啟動器
sudo gedit /usr/bin/eclipse
添加如下內容
#!/bin/sh
export MOZILLA_FIVE_HOME="/usr/lib/mozilla/"
export ECLIPSE_HOME="/usr/local/eclipse"
$ECLIPSE_HOME/eclipse $*
3.添加可執行權限
sudo chmod +x /usr/bin/eclipse
4.在開始菜單中輸入eclipse:

就會看到軟件圖標,然后將其拖到左側工具條中即可。

-
下載hadoop在eclise中的插件並配置
直接在網上搜: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 查看
-
編寫HelloWorld
環境搭建好了,之前運行Hadoop時,直接用了examples中的示例程序跑了下,現在可以自己來寫這個HelloWorld了。
在eclipse菜單下 new Project 可以看到,里面增加了Map/Reduce選項:

選中,點下一步:

輸入項目名稱后,繼續(next), 再點Finish

然后在Project Explorer中就可以看到該項目了,展開,src發現里面啥也沒有,於是右健菜單,新建類(new->new class):

然后點擊Finish,就可以看到創建了一個java類了:

然后在這個類中填入代碼:
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 {
System.out.println("key=" +key.toString());
System.out.println("Value=" + value.toString());
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();
System.out.println("url:" + conf.get("fs.default.name"));
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);
}

填入代碼后,會看到一些錯誤,沒關系,點擊邊上的紅叉,然后選擇里面的import即可;
如果想偷懶,則可以直接在類的開頭帖入下面的這些引用:
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;
這里,如果直接用源碼來操作,可能會GenericOptionsParser這個類找不到定義,還是紅叉,沒關系,如果還是紅叉,可以添加commons-cli-1.2.jar
這個jar包,在build/ivy/lib/Hadoop/Common下,右健Project Explorer中的MyHelloWorld工程,選擇Build Path->Config Build Path

在Liberaries Tab頁下,點擊Add External JARs 在彈出窗口中,跟據前面說的目錄,找到這個jar包,點確定后,回到工程,可以看到紅叉消失,說明編譯都通過了。
在確保整個工程沒有錯誤后,點擊上面的小綠箭頭
,然后在彈出的小窗口上,選擇Run On Hadoop:

點OK后,會彈出小窗口:

然手中選擇Choose an existing server from the list below。然后找到之前配置的地址項,選中后,點Finish,然后系統不會Run起來,在控制台(雙擊可最大化)中可以看到運行結果:

運行完后,用命令行可以看到 $bin/hadoop fs –ls 可以看到多了一個out文件夾,再用$bin/hadoop fs –cat out/*可以將out文件夾內容全顯示出來,則可以看到單詞的統計結果來。
問題1 :過程中,如果點了Run On Hadoop沒有反應,則可能你下的這個有問題,重新到:https://issues.apache.org/jira/secure/attachment/12460491/hadoop-eclipse-plugin-0.20.3-SNAPSHOT.jar
上下載,然后將下載的插件重命名為"hadoop-0.20.2-eclipse-plugin.jar",放入eclipse中的plugins目錄下。
問題2:運行后,如果結果里只輸入了個usage <in> <out>,則需要修改下參數,在運行菜單邊上小箭頭,下拉,點擊Run Configuration,:

左邊選中 JavaApplication中的 WordCount,右邊,在Arguments中輸入 in out。
然后再點Run 就可以看到結果了。
問題3:第二次運行會報錯,仔細看提示,可以看到報錯的是out目錄已經存在,所以需要手動來刪除一下。
好了,結果出來了,該收工了!
什么?收工? 還沒看懂程序呢!!
不急。一口吃不了胖子,慢慢來,學一些新東西,我喜歡先依葫蘆畫瓢然后再慢慢深入。 先能讓程序入。 先能讓程序正常跑起來,然后再來邊學邊改邊運行。
