1. 程式人生 > >(2)Hadoop筆記:hadoop-eclipse-plugin外掛的安裝和mapReduce小栗子

(2)Hadoop筆記:hadoop-eclipse-plugin外掛的安裝和mapReduce小栗子

注:
1.eclipse所在環境為windows
2.hadoop版本2.8.3
3.hadoop-eclipse-plugin版本2.8.3
4.eclipse版本Luna Service Release 1 (4.4.1)
5.JDK 1.7

  • 外掛安裝

hadoop-eclipse-plugin編譯
因為我本地使用的JDK為1.7,而現在網上能找到的hadoop-eclipse-plugin-2.8.3都是基於JDK1.8編譯的,所以都不能使用,因此需要下載hadoop-eclipse-plugin的原始碼然後在本地編譯,過程中需要Hadoop-2.8.3的支援。當然如果你能找到符合自己環境的外掛包,這步就可以跳過了。

Hadoop-2.8.3.tar.gz
hadoop2x-eclipse-plugin (github託管的原始碼)
apache-ant-1.9.11-bin.zip
下載完後解壓apache-ant-1.9.11-bin.zip,並配置環境變數。
新建ANT_HOME=E:apache-ant-1.9.4
在PATH後面加;%ANT_HOME%\bin
測試下

ant -version

這裡寫圖片描述

解壓Hadoop-2.8.3.tar.gz,hadoop2x-eclipse-plugin
編輯E:\hadoop2x-eclipse-plugin-master\src\contrib\eclipse-plugin\build.xml
新增下圖紅框中的部分,3項代表的意思應該都懂,就不多說了。
這裡寫圖片描述

然後往下翻能發現有一堆這個東西,之後編譯時大概會出錯的地方。先開啟放在這,不用修改。①
這裡寫圖片描述

然後編輯E:\hadoop2x-eclipse-plugin-master\ivy\libraries.properties.xml
一般來講只要修改下紅框中的版本即可,然後這裡有一大堆版本,而上面①圖中那些都是在引用這裡的版本。這裡的版本又對應著Hadoop-2.8.3中的資源。在編譯時可能會出現這裡寫的版本和Hadoop實際用的版本不一樣導致找不到jar包的報錯,這時就可以根據報錯資訊來修改下方的版本號,使得符合實際。基本都在${hadoop.home}/share/hadoop/common/lib資料夾中
這裡寫圖片描述

進入hadoop2x-eclipse-plugin-master\src\contrib\eclipse-plugin目錄,執行cmd命令列

ant jar

編譯完成,遇到錯誤就根據提示修改,最大可能遇到的就是我上面提到的問題,還有當編譯時長時間卡在ivy-resolve-common: 處時,大概率已經編譯失敗。
這裡寫圖片描述

編譯完成後的檔案在
hadoop2x-eclipse-plugin-master\build\contrib\eclipse-plugin資料夾中
這裡寫圖片描述

將jar包放入eclipse/plugins資料夾中,重啟eclipse
可以看到如下圖示
這裡寫圖片描述
新增
window->show view->other
這裡寫圖片描述

配置連線,如下圖所示,隨便取個名字就行
這裡寫圖片描述

然後如果連線成功的話就如下圖所示,這裡剛新搭建的Hadoop環境的話應該一開始就是空的,所以可能會拋空指標異常,沒什麼影響的,直接新建東西就行。
這裡寫圖片描述

這裡寫圖片描述

通過這個我們可以輕鬆快捷的將檔案上傳給Hadoop檔案系統,方便本地除錯。

window->preferences,選擇Hadoop檔案,這裡主要目的是可以直接引用相關jar包
這裡寫圖片描述

  • 使用例子,單詞計數
    首先需要下載hadoop.dll,這個網上找找對應版本的吧,我用的是2.X的,放在C/windows/System32下。

File->New->other
next,填寫名字,finish
這裡寫圖片描述

這裡寫圖片描述

新建4個檔案
這裡寫圖片描述
WordCountMapper.java

package com.hadoop.demo;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

/*
 * KEYIN:輸入kv資料對中key的資料型別
 * VALUEIN:輸入kv資料對中value的資料型別
 * KEYOUT:輸出kv資料對中key的資料型別
 * VALUEOUT:輸出kv資料對中value的資料型別
 */
public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable>{

    /*
     * map方法是提供給map task程序來呼叫的,map task程序是每讀取一行文字來呼叫一次我們自定義的map方法
     * map task在呼叫map方法時,傳遞的引數:
     *      一行的起始偏移量LongWritable作為key
     *      一行的文字內容Text作為value
     */
    @Override
    protected void map(LongWritable key, Text value,Context context) throws IOException, InterruptedException {
        //拿到一行文字內容,轉換成String 型別
        String line = value.toString();
        //將這行文字切分成單詞
        String[] words=line.split(" ");

        //輸出<單詞,1>
        for(String word:words){
            context.write(new Text(word), new IntWritable(1));
        }
    }
}

WordCountReducer.java

package com.hadoop.demo;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

/*
 * KEYIN:對應mapper階段輸出的key型別
 * VALUEIN:對應mapper階段輸出的value型別
 * KEYOUT:reduce處理完之後輸出的結果kv對中key的型別
 * VALUEOUT:reduce處理完之後輸出的結果kv對中value的型別
 */
public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable>{
    @Override
    /*
     * reduce方法提供給reduce task程序來呼叫
     * 
     * reduce task會將shuffle階段分發過來的大量kv資料對進行聚合,聚合的機制是相同key的kv對聚合為一組
     * 然後reduce task對每一組聚合kv呼叫一次我們自定義的reduce方法
     * 比如:<hello,1><hello,1><hello,1><tom,1><tom,1><tom,1>
     *  hello組會呼叫一次reduce方法進行處理,tom組也會呼叫一次reduce方法進行處理
     *  呼叫時傳遞的引數:
     *          key:一組kv中的key
     *          values:一組kv中所有value的迭代器
     */
    protected void reduce(Text key, Iterable<IntWritable> values,Context context) throws IOException, InterruptedException {
        //定義一個計數器
        int count = 0;
        //通過value這個迭代器,遍歷這一組kv中所有的value,進行累加
        for(IntWritable value:values){
            count+=value.get();
        }

        //輸出這個單詞的統計結果
        context.write(key, new IntWritable(count));
    }
}

WordCountJobSubmitter.java

package com.hadoop.demo;

import java.io.IOException;
import java.util.Date;

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.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class WordCountJobSubmitter {

    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        Configuration conf = new Configuration();
        Job wordCountJob = Job.getInstance(conf);

        //重要:指定本job所在的jar包
        wordCountJob.setJarByClass(WordCountJobSubmitter.class);

        //設定wordCountJob所用的mapper邏輯類為哪個類
        wordCountJob.setMapperClass(WordCountMapper.class);
        //設定wordCountJob所用的reducer邏輯類為哪個類
        wordCountJob.setReducerClass(WordCountReducer.class);

        //設定map階段輸出的kv資料型別
        wordCountJob.setMapOutputKeyClass(Text.class);
        wordCountJob.setMapOutputValueClass(IntWritable.class);

        //設定最終輸出的kv資料型別
        wordCountJob.setOutputKeyClass(Text.class);
        wordCountJob.setOutputValueClass(IntWritable.class);

        Long fileName = (new Date()).getTime();

        //設定要處理的文字資料所存放的路徑
        FileInputFormat.setInputPaths(wordCountJob, "hdfs://xx.xx.xx.xx:9002/test/1.data");
        FileOutputFormat.setOutputPath(wordCountJob, new Path("hdfs://xx.xx.xx.xx:9002/test/"+fileName));

        //提交job給hadoop叢集
        wordCountJob.waitForCompletion(true);
    }
}

log4j.properties

log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spring.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

然後準備下1.data的資料(就是個txt編輯後修改後綴為data的檔案),將該檔案通過DFS上傳

hello tom
hello jim
how are you
i love you
i miss you
i love you

這裡寫圖片描述

因為我這裡放的路徑是test下,實際使用時請在WordCountJobSubmitter .java中替換為自己的路徑和檔名。

執行,選中WordCountJobSubmitter.java(有main函式的),右鍵run as ->run configurations。hdfs第一行為輸入,第二行為輸出
這裡寫圖片描述

執行,可以看見生成了新的檔案,點選檢視,可以看到單詞計數的結果了。
這裡寫圖片描述

因為大部分都是根據記憶寫的,所以過程中如果出現錯誤,望指正 _ (:з」∠*)_。