大数据之MapReduce(MR)

MapReduce是一个分布式计算框架。思想:将复杂问题分解成若干规模较小的部分,对每个部分进行逐个解决,再将每部分的结果进行合并得到最终结果。
在这里插入图片描述
Map阶段:对一组数据进行某种重复式的处理

Reduce阶段:对Map的中间结果进一步处理

Map和Reduce为两个抽象编程接口,由用户去编程实现:

map:(k1,v1)转换成(k2,v2)

reduce:(k2,[v2])转换成(k3,v3)

MapReduce特点:

  • 易于编程,提供二次开发接口。但现在来说,Spark、Flink等计算框架更加容易与普遍,Spark吃内存,Flink吃CPU
  • 良好的扩展性:可将计算节点增至成百上千,轻松处理TB级或PB级数据
  • 高容错:一台节点宕机,计算任务会转移
  • 适合海量数据离线处理

一个完整的MapReduce分布式运行时有三类:

  • MRAppMaster:负责整个MR程序的过程调度及状态协调
  • MapTask:负责map阶段的整个数据处理流程
  • ReduceTask:负责reduce阶段的整个数据处理流程

阶段组成:

Map后面只能跟Reduce或者直接结束,不能多个Map相邻

执行MapReduce程序示例:

计算圆周率:

cd /export/server/hadoop-3.3.0/sbin #进入Hadoop文件夹
./start-all.sh#启动Hadoop集群
cd /export/server/hadoop-3.3.0/share/hadoop/mapreduce#进入示例文件夹
hadoop jar hadoop-mapreduce-examples-3.3.0.jar pi 2 2#启动计算圆周率的MR程序

单词计数WordCount编程思路:

1、map:数据切割并标记个数,输出格式[单词,1]

2、shuffle:把相同key分成一组

3、reduce:对每组的value进行累加得到每个单词的计数

首先,新建一个txt文件并上传到HDFS,并执行示例MR程序

 hadoop jar hadoop-mapreduce-examples-3.3.0.jar wordcount /test /test/output

通过查看HDFS路径下 /test/output/part-r-00000文件来查看结果
在这里插入图片描述
MR内部执行流程
在这里插入图片描述

1、Map流程**

  1. 将输入文件按照一定标准进行逻辑切片,默认切片大小和块大小一样(128M),每个切片由MapTask处理
  2. 对切片中数据按照规则读取返回key-value对,默认按行读取。key是每一行的起始文职偏移量,value是本行的文本内容。(TextInputFormat)
  3. 调用Mapper类中方法处理数据
  4. 按照一定规则对键值对进行分区partition
  5. Map输出写入内存,达到比例溢出写到磁盘上。溢出spill时候根据key进行排序
  6. 对溢出文件进行合并merge形成最终文件

2、Reduce流程

  1. ReduceTask主动从MapTask复制拉取自己要处理的数据
  2. 把拉到的数据进行merge合并并排序
  3. 对排序的key-value使用reduce,把键相等的放在一起最后写到HDFS中。

3、shuffle

在MR中,map输出之后到reduce输入之前为shuffle过程,即从无序到有序。shuffle的过程如下图。
在这里插入图片描述

map端shuffle:
  • collect阶段:map结果输出到环形缓冲区,保存前对key进行Hash分区
  • spill阶段:内存中数据达到阈值写入磁盘,写入磁盘前进行排序
  • merge阶段:对溢出的临时文件进行合并,得到一个最终的输出数据
reduce端shuffle:
  • copy阶段:reduce启动fetcher线程到已完成的节点上复制一份属于自己的数据
  • merge阶段:在copy的同时,后台开启两个线程对内存到本地的数据文件进行合并操作
  • sort阶段:merge同时进行排序操作,保证opy的数据整体有效性

4、代码编写MR程序

  1. 数据类型
    在这里插入图片描述
    2、配置Windows下环境变量
  • 解压hadoop-3.3.0.tar.gz并配置环境变量,下载winutil 和 hadoop.ddl文件,下载地址:https://github.com/steveloughran/winutils/tree/master/hadoop-3.0.0/bin

  • 将hadoop-3.3.0.tar.gz文件解压后,准备对应版本的hadoop.dll和winutils.exe文件,放到hadoop的斌文件夹,如:E:\learn\BigData\Hadoop\hadoop-3.3.0.tar\hadoop-3.3.0\bin

  • 在这里插入图片描述
    在这里插入图片描述

  • 配置完成,双击winutil 文件无报错,在 cmd 输入"hadoop version",查看版本信息

报错图片
在这里插入图片描述
编辑hadoop-env.cmd文件

set JAVA_HOME=%JAVA_HOME%

修改为:

  set JAVA_HOME=C:\PROGRA~1\Java\jdk1.8.0_144

在这里插入图片描述
3、编写程序

maven

<dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.8.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>${hadoop.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>${hadoop.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>${hadoop.version}</version>
</dependency>
  • map程序
package MRDemo;

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

import java.io.IOException;

public class TestMap extends Mapper<LongWritable, Text, Text, IntWritable> {
    private Text t = new Text();
    private IntWritable out=new IntWritable(1);
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        String s = value.toString();
        String[] split = s.split(" ");
        for (String s1 : split) {
            t.set(s1);
           context.write(t,out);
        }
    }
}

  • reduce程序
package MRDemo;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

import java.io.IOException;

public class TestReduce extends Reducer<Text, IntWritable, Text, IntWritable> {
    IntWritable out=new IntWritable();
    int sum=0;
    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
        for (IntWritable value : values) {
            sum=sum+value.get();
        }
        out.set(sum);
        context.write(key,out);
    }
}

  • 驱动程序(整合程序),将map和reduce连接起来
package MRDemo;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
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;

import java.io.IOException;

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

        job.setJarByClass(TestMapReduce.class);

        job.setMapperClass(TestMap.class);
        job.setReducerClass(TestReduce.class);

        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        FileInputFormat.setInputPaths(job,new Path("C:\\Users\\Administrator\\Desktop\\input\\test.txt"));
        FileOutputFormat.setOutputPath(job,new Path("C:\\Users\\Administrator\\Desktop\\output"));
        boolean result = job.waitForCompletion(true);
        System.exit(result?0:1);
//        job.submit();


    }
}

其中输入数据为

hadoop spark hive
sqoop flink
hadoop hive
spark flink

输出数据为

flink	2
hadoop	4
hive	6
spark	8
sqoop	9

注意:输出的文件夹为不存在的文件夹,权限问题可在idea的虚拟机选项里-DHADOOP_USER_NAME=root

  • 19
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值