Hadoop系列(七)Hadoop三大核心之MapReduce-程序編寫


接下來以一個簡單的WordCount爲例子,介紹Java版本的MapReduce的程序編寫。

mapreduce程序主要分三部分:1.map部分,2.reduce部分,3.提交部分。

1. 準備部分

hadoop中,針對數據類型自成一體,與java的數據類型對應。封裝在hadoop.io包中,主要分爲基本類型和其它類型。

  • 基本數據類型
數據類型 hadoop數據類型 Java數據類型
布爾 BooleanWritable boolean
整型 IntWritable int
長整型 LongWritable long
浮點型 FloatWritable float
雙精浮點 DoubleWritable double
字節 ByteWritable byte
  • 其它類型
數據類型 hadoop數據類型 Java數據類型
字符串 Text String
數組 ArrayWritable Array
Map MapWritable Map

2. jar包依賴

創建一個maven工程,pom.xml文件中,添加以下依賴

<dependencies>
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-common</artifactId>
        <version>2.6.0</version>
    </dependency>

    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-hdfs</artifactId>
        <version>2.6.0</version>
    </dependency>

    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-client</artifactId>
        <version>2.6.0</version>
    </dependency>
</dependencies>

3. Map部分

映射部分,將數據逐條處理

首先,需要繼承Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>類

四個泛型參數分別代表:輸入key 輸入value 輸出key 輸出value

然後重寫mapper的map方法

map(KEYIN key, VALUEIN value, Context context) throws IOException, InterruptedException

主體代碼:

public class WordCountMap extends Mapper<LongWritable, Text, Text, IntWritable> {

    /**
     *  流程,輸入key和value,map的結果寫入到context中
     */
    @Override
    public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        //讀取一行數據
        String line = value.toString();
        //因爲英文字母是以“ ”爲間隔的,因此使用“ ”分隔符將一行數據切成多個單詞並存在數組中
        String str[] = line.split(" ");
        //循環迭代字符串,將一個單詞變成<key,value>形式,及<"hello",1>
        for (String s : str) {
            context.write(new Text(s), new IntWritable(1));
        }
    }

}

4.Reduce部分

歸併部分,將map處理和shuffle之後的數據進行歸併。shuffle過程由hadoop控制

Reducer<KEYIN,VALUEIN,KEYOUT,VALUEOUT>

四個泛型參數分別代表:輸入key 輸入value 輸出key 輸出value

然後重寫reducer的reduce方法

reduce(KEYIN key, Iterable<VALUEIN> values, Context context) throws IOException, InterruptedException

主體代碼:

public class WordCountReduce extends Reducer<Text,IntWritable,Text, IntWritable> {
    /**
     *  流程,輸入key和value,map的結果寫入到context中
     */
    @Override
    public void reduce(Text key, Iterable<IntWritable> values,Context context)throws IOException,InterruptedException{
        int count = 0;

        for(IntWritable value: values) {
            count++;
        }
        context.write(key,new IntWritable(count));
    }
}

5.提交部分

mapreduce的入口

public static void main(String[] args) throws Exception{
    Configuration conf = new Configuration();
    // 構造一個job對象來封裝本mapreduce業務到所有信息
    Job mrJob = Job.getInstance(conf);
    // 指定本job工作用到的jar包位置
    mrJob.setJarByClass(WordCount.class);
    // 指定本job用到的mapper類
    mrJob.setMapperClass(WordCountMap.class);
    // 指定本job用到的reducer類
    mrJob.setReducerClass(WordCountReduce.class);

    // 指定mapper輸出的kv類型
    mrJob.setMapOutputKeyClass(Text.class);
    mrJob.setMapOutputValueClass(IntWritable.class);


    // 指定reducer輸出到kv數據類型(setOutputKeyClass 會對mapper和reducer都起作用,如果上面mapper不設置的話)
    mrJob.setOutputKeyClass(Text.class);
    mrJob.setOutputValueClass(IntWritable.class);


    FileInputFormat.addInputPath(mrJob,new Path(args[0]));

    //設置mapreduce程序的輸出路徑,MapReduce的結果都是輸入到文件中
    FileOutputFormat.setOutputPath(mrJob,new Path(args[1]));

    // 最後提交任務
    boolean waitForCompletion = mrJob.waitForCompletion(true);
    System.exit(waitForCompletion ? 0 : 1);
}

6.打包提交

將程序打成jar包,提交到hadoop集羣中,然後使用命令行進行任務提交

對於輸入輸出路徑,均可接受本地路徑和hdfs路徑。

本地路徑前綴:file://

hdfs路徑前綴:hdfs://

/hadoop-3.1.2/bin/hadoop jar my_mapreduce-1.0-SNAPSHOT.jar com.breakthrough.wordcount.WordCount file:///home/hadoop/english.txt file:///home/hadoop/output
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章