MapReduce概述和例子實現

MapReduce概述:

MapReduce是一種分佈式計算模型,由Google提出,主要用於搜索領域,解決海量數據的計算問題。
MR由兩個階段組成:Map和Reduce,用戶只需要實現map()和reduce()兩個函數,即可實現分佈式計算,非常簡單。
這兩個函數的形參是key,value對,表示函數的輸入信息。

執行步驟:
1、map任務處理
1.1讀取輸入文件內容,解析成key、value對。對輸入文件的每一行,解析成key、value對。每一個鍵值對調用一次map函數。
1.2寫自己的邏輯,對輸入的key、value處理,轉換成新的key、value輸出。
1.3對輸出的key、value進行分區。
1.4對不同分區的數據,按照key進行排序、分組。相同key和value放到一個集合中。
1.5(可選)分組後的數據進行歸約。

2、reduce任務處理
2.1對多個map任務的輸出,按照不同的分區,通過網絡copy到不同的reduce節點
2.2對多個map任務的輸出進行合併、排序。寫reduce函數自己的邏輯,對輸入的key、value處理,轉換成新的key、value輸出。
2.3把reduce的輸出保存到文件中。

map、reduce鍵值對格式
函數 輸入鍵值對 輸出鍵值對
map() <k1,v1> <k2,v2>
reduce() <k1,{v2}> <k3,v3>

MapperReduce的原理圖如下:
在這裏插入圖片描述

例子:實現WCCount
流程圖如下:
在這裏插入圖片描述
代碼實現如下::::(注意導的包哦)
Mapper實現:

package com.zhou.hadoop.mr;

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

import java.io.IOException;

public class WCMapper extends Mapper<LongWritable, Text, Text, LongWritable> {

    /**
     * 解釋:Mapper需要實現序列化,因爲有些數據是需要寫到磁盤然後傳遞的
     * LongWritable和Text都是hadoop實現的序列化的機制,hadoop沒有使用jdk默認的序列化機制
     * Long和String本身就實現了序列化機制
     * Long的化身就是LongWritable,String的化身就是Text
     * @param key
     * @param value
     * @param context
     * @throws IOException
     * @throws InterruptedException
     */
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        //根據思想,輸入的值是-key:偏移量 value:每行數據
        //        輸出的值是-key:字符串  value:1(因爲按照每個字母是1個,後續好計算)

        //accept
        String line = value.toString();
        //split  按照空格分隔字母
        String[] words = line.split(" ");

        //loop
        for (String w : words) {
            //send
            context.write(new Text(w), new LongWritable(1));
        }
    }
}

Reduce實現:

package com.zhou.hadoop.mr;

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

import java.io.IOException;

public class WCReduce extends Reducer <Text, LongWritable, Text, LongWritable>{

    /**
     * 解釋:
     * 此方法是接收mapper方法傳遞過來的數值,然後進行彙總等一系列的處理
     * @param key
     * @param values
     * @param context
     * @throws IOException
     * @throws InterruptedException
     */
    @Override
    protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
        //define a counter
        long counter=0;
        //loop
        for (LongWritable l:values) {
            counter+=l.get();
        }
        context.write(key,new LongWritable(counter));

    }
}

WCCount實現:

package com.zhou.hadoop.mr;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

/**
 * 1、分析具體的業務邏輯,確定輸入輸出數據的樣式
 * 2、自定義一個類,這個類要繼承mapper類,重寫map方法,
 * 在map方法實現具體業務邏輯,將新的key,value輸出
 *3、自定義一個類,這個類要繼承Reduce類,重寫reduce方法,
 *在reduce方法中實現具體業務邏輯
 * 4、將自定義的mapper和reduce統計job對象組裝起來
 */
public class WCCount {
    public static void main(String[] args) throws Exception {

        //構建job對象
        Job job = Job.getInstance(new Configuration());

        //注意:main方法所在的類
        job.setJarByClass(WCCount.class);

        //設置Mapper相關屬性
        job.setMapperClass(WCMapper.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(LongWritable.class);
        FileInputFormat.setInputPaths(job, new Path("/words"));

        //設置reducer相關屬性
        job.setReducerClass(WCReduce.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(LongWritable.class);
        FileOutputFormat.setOutputPath(job, new Path("/wcount"));

        //提交任務  true是代表打印日誌,false不打印日誌
        job.waitForCompletion(true);


    }
}

編寫完代碼之後,測試的話需要打jar包部署在hadoop環境上進行測試。
使用hadoop jar 的命令進行測試

MR1.0流程講解:
1.執行MR的命令:
hadoop jar <jar在linux的路徑> <main方法所在的類的全類名> <參數>
例子:

	hadoop jar /root/wc1.jar cn.itcast.d3.hadoop.mr.WordCount hdfs://itcast:9000/words /out2

2.MR執行流程
(1).客戶端提交一個mr的jar包給JobClient(提交方式:hadoop jar …)
(2).JobClient通過RPC和JobTracker進行通信,返回一個存放jar包的地址(HDFS)和jobId
(3).client將jar包寫入到HDFS當中(path = hdfs上的地址 + jobId)
(4).開始提交任務(任務的描述信息,不是jar, 包括jobid,jar存放的位置,配置信息等等)
(5).JobTracker進行初始化任務
(6).讀取HDFS上的要處理的文件,開始計算輸入分片,每一個分片對應一個MapperTask
(7).TaskTracker通過心跳機制領取任務(任務的描述信息)
(8).下載所需的jar,配置文件等
(9).TaskTracker啓動一個java child子進程,用來執行具體的任務(MapperTask或ReducerTask)
(10).將結果寫入到HDFS當中

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章