hadoop實戰--搭建開發環境及編寫Hello World


本文地址:http://www.cnblogs.com/archimedes/p/hadoop-helloworld.html,轉載請注明源地址。

歡迎關注我的個人博客:www.wuyudong.com, 更多雲計算與大數據的精彩文章

1、下載

整個Hadoop是基於Java開發的,所以要開發Hadoop相應的程序就得用java方便

進入網站:http://archive.eclipse.org/eclipse/downloads/

選擇3.71 eclipse SDK 進入下面的頁面:

http://archive.eclipse.org/eclipse/downloads/drops/R-3.7.1-201109091335/#EclipseSDK

選擇相關的版本下載JDK,我選擇的版本是:eclipse-SDK-3.7.1-linux-gtk

PS:查看linux系統是32位的還是64位的,可以使用下面的命令:

#uname -a

由於我的系統是32位的,所有選擇相應的linux版本

2、解壓縮

下載下來一般是tar.gz文件,運行:

$tar -zxvf eclipse-SDK-3.7.1-linux-gtk.tar.gz -C ~/opt

這里opt是需要解壓的目錄,我習慣將一些軟件放在opt文件夾中

解完后,在opt文件夾下,就可以看到eclipse文件夾。

運行:$~/opt/eclipse/eclipse

3、下載hadoop在eclise中的插件並配置

直接進入:http://www.java2s.com/Code/Jar/h/Downloadhadoop0202eclipsepluginjar.htm

注意:下載下來的是:hadoop-0.20.2-eclipse-plugin.jar.zip,先解壓縮成 hadoop-0.20.2-eclipse-plugin.jar

當然,更加簡單的方法是:hadoop-0.20.2/contrib/eclipse-plugin/文件夾中有個hadoop-0.20.2-eclipse-plugin.jar

將jar包放在eclipse安裝目錄下的plugins文件夾下。然后啟動eclipse

進入后,在菜單window->Rreferences下打開設置:

點擊“Ant” 出現:

點擊browse選擇hadoop的源碼下的build目錄,然后點OK

打開Window->Show View->Other 選擇Map/Reduce Tools,單擊Map/Reduce Locations,會打開一個View:

添加Hadoop Loacation,其中Host和Port的內容這里的host和port對應mapred-site.xml中mapred.job.tracker的值,UserName 是用戶名,我配置的是localhost和9001

但是出現如下問題,eclipse的左側看不到project explorer,更看不到其中的dfs

解決辦法:

應該在菜單欄

選擇:Window->Open pespective-><Map/Reduce>。然后就能看到HDFS文件系統已經所創建得一些項目。

添加Hadoop Loacation,其中Host和Port的內容跟據conf/hadoop-site.xml的配置填寫,UserName 是用戶名,如下圖

成功添加Hadoop Loacation后還可能出現如下錯誤:

解決辦法:

這時候,需要對namenode進行格式化:bin/hadoop namenode -format  

執行命令:bin/start-all.sh

如果test下面的文件夾顯示(1)而不是(2)也是正常的,如果要顯示(2),運行《安裝並運行hadoop》一文中最后的那幾個命令。

在配置完后,在Project Explorer中就可以瀏覽到DFS中的文件,一級級展開,可以看到之前我們上傳的in文件夾,以及當是存放的2個txt文件,同時看到一個在計算完后的out文件夾。

現在我們要准備自己寫個Hadoop 程序了,所以我們要把這個out文件夾刪除,有兩種方式,一是可以在這樹上,執行右健刪除。 二是可以用命令行:

$ bin/hadoop fs -rmr out

用$bin/hadoop fs -ls 查看

4、編寫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 {
      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);
  }

填入代碼后,會看到一些錯誤,沒關系,點擊邊上的紅叉,然后選擇里面的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起來,在控制台(雙擊可最大化)中可以看到運行結果:

運行完后,可以看到多了一個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:

運行后,如果Console里只輸出Usage :wordcount<in> <out>,

則需要修改下參數,在運行菜單邊上小箭頭,下拉,點擊Run Configuration,:

左邊選中 JavaApplication中的 WordCount,右邊,在Arguments中輸入 in out。然后再點Run 就可以看到結果了。

左邊選中 JavaApplication中的 WordCount,右邊,在Arguments中輸入 in out。然后再點Run 就可以看到結果了。

問題3:

第二次運行會報錯,仔細看提示,可以看到報錯的是out目錄已經存在,所以需要手動來刪除一下。

更進一步

上面我們寫了一個MapReduce的HelloWorld程序,現在,我們就也學一學HDFS程序的編寫。HDFS是什么,它是一個分布式文件存儲系統。一般常用操作有哪些? 當然我們可以從編程角度來:創建、讀、寫一個文件,列出文件夾中的文件及文件夾列表,刪除文件夾,刪除目錄,移動文件或文件夾,重命名文件或文件夾。

啟動eclipse,新建Hadoop項目,名稱MyHDFSTest,新建類HDFSTest,點擊確定,然后同樣工程屬性Configure BuildPath中把 build/ivy/lib/Hadoop下的所有jar包都引用進來(不詳細說明了,可參考上面的步驟)

在類中,添加main函數:

public static void main(String[] args) {
}

或者也可以在添加類時,勾選上創建main,則會自動添加上。

在mian函數中添加以下內容:

try {
    Configuration conf = new Configuration();
    conf.set("fs.default.name", "hdfs://localhost:9000");
    FileSystem hdfs = FileSystem.get(conf);
    Path path = new Path("in/test3.txt");
    FSDataOutputStream outputStream = hdfs.create(path);
    byte[] buffer = "Hello".getBytes();
    outputStream.write(buffer, 0, buffer.length);
    outputStream.flush();
    outputStream.close();
    System.out.println("Create OK");
    } catch (IOException e) {
    e.printStackTrace();
}

直接添加進來會報錯,然后需要添加一些引用才行:

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

在沒有錯誤后,點擊工具條上的運行, 但這次跟前次不一樣,選擇Run as Java Application。然后,就可以在輸出框中看到Create OK的字樣了,表明程序運行成功。

這段代碼的意思是在in文件夾下,創建test3.txt,里面的內容是"Hello"。 在運行完后,我們可以到eclipse的Project Explorer中查看是否有這文件以及內容。同樣也可以用命令行查看$bin/hadoop fs -ls in。

ok,第一個操作HDFS的程序跑起來了,那其它功能只要套上相應的處理類就可以了。為了方便查找操作,我們列舉了張表:

操作說明

操作本地文件

操作DFS文件

主要命名空間

java.io.File

java.io.FileInputStream

java.io.FileOutputStream

org.apache.hadoop.conf.Configuration

org.apache.hadoop.fs.FileSystem

org.apache.hadoop.fs.Path

org.apache.hadoop.fs.FSDataInputStream;

org.apache.hadoop.fs.FSDataOutputStream

初使化對象

new File(路徑);

Configuration

FileSystem hdfs

創建文件

File.createNewFile();

FSDataOutputStream = hdfs.create(path)

FSDataOutputStream.write(

buffer, 0, buffer.length);

創建文件夾

File.mkdir()

hdfs.mkdirs(Path);

讀文件

new FileInputStream();

FileInputStream.read(buffer)

FSDataInputStream = hdfs.open(path);

FSDataInputStream.read(buffer);

寫文件

FileOutputStream.write(

buffer, 0, buffer.length);

FSDataOutputStream = hdfs.append(path)

FSDataOutputStream.write(

buffer, 0, buffer.length);

刪除文件(夾)

File.delete()

FileSystem.delete(Path)

列出文件夾內容

File.list();

FileSystem.listStatus()

重命令文件(夾)

File.renameTo(File)

FileSystem.rename(Path, Path)        

有了這張表,以后在需要的時候就可以方便查詢了。

參考資料:

1、http://www.cnblogs.com/zjfstudio/p/3870762.html

2、http://www.cnblogs.com/xia520pi/archive/2012/05/16/2504205.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM