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的原理图如下:

mapreduce进行表的增删改查 mapreduce实例及数据_hadoop

例子:实现WCCount

流程图如下:

mapreduce进行表的增删改查 mapreduce实例及数据_mapreduce进行表的增删改查_02


代码实现如下::::(注意导的包哦)

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当中