MapReduce学习笔记

MapReduce学习笔记

总感觉自己学一点忘一点,所以想通过博客来加深自己的印象,想对自己所学的知识做一个总结,如果有书写不对的地方,请各位见谅,并指出其中的错误之处,万分感激。

一、MapReduce基本概念

1、mapreduce的思想

    MapReduce是Hadoop的三大组件之一,是一个分布式运算程序的编程模型,核心功能是将用户编写的业务逻辑代码和自带默认的组件,整合成一个完整的分布式运算程序,并发的运行在Hadoop的集群上。

    MapReduce的核心思想是“分而治之”,使用于大量复杂的任务处理场景

    Map负责“分”:把复杂的任务分解为若干个“简单的任务”,来并行的处理。可以进行拆分的前提的是这些小任务是并行计算的,彼此之间几乎没有依赖

    Reduce负责“合”:即是对Map端的结果进行全局的汇总

    这两个阶段的合并就是对MapReduce思想的具体体现,举个例子:我们要去数图书馆的所有书,你去数1号书架,我去数2号书架,这就是“Map”,然后我们把所有人的统计数累加在一起,这就是“Reduce”。

2、MapReduce的设计构思
    1、如何处理大量的数据:分而治之

             对互相间不具有依赖计算关系的大数据,实现并行最自然的办法就是采取分而治之的策略。但是并行计算的第一个重要问题就是如何划分计算任务或者计算数据以便对划分的子任务或者数据块同时进行计算。不可拆分的计算任务或者相互间互有依赖关系的数据是无法进行计算的。

    2、构建抽象模型:Map和Reduce

             MapReduce借助了函数式语言的编程思想,并且提供了Map和Reduce两个清晰的操作接口:
             Map对一组数据进行某种重复性的处理。
             Reduce对Map的中间结果进行结果的整合。

    3、统一构架,隐藏系统层细节

      如何提供统一的计算框架,如果没有统一封装底层细节,那么程序员则需要考虑诸如数据存储、划分、分发、结果收集、错误恢复等诸多细节;为此,MapReduce设计并提供了统一的计算框架,为程序员隐藏了绝大多数系统层面的处理细节。
      MapReduce最大的亮点在于通过抽象模型和计算框架把需要做什么(what need to do)与具体怎么做(how to do)分开了,为程序员提供一个抽象和高层的编程接口和框架。程序员仅需要关心其应用层的具体计算问题,仅需编写少量的处理应用本身计算问题的程序代码。如何具体完成这个并行计算任务所相关的诸多系统层细节被隐藏起来,交给计算框架去处理:从分布代码的执行,到大到数千小到单个节点集群的自动调度使用。

3、mapreduce的框架结构
一个完整的mapreduce程序在分布式运行时有三类实例进程
  1. MRAppMaster:负责整个程序的过程调度以及状态的协调
  2. MapTask:负责map阶段的数据处理流程
  3. ReduceTask:负责reduce阶段的整个数据处理流程
    在这里插入图片描述
                                                Mapreduce基于yarn上的运行流程

二、MapReduce执行流程

这是我从官网找到的mapreduce的执行流程,但是有点抽象!不太好理解。

在这里插入图片描述

下图,为我根据官网的图片绘制的mapreduce的执行流程以及自己的理解,如果有书写不正确的地方,请各位大佬留下宝贵的建议。鉴于图片太大,因此分为了map图解和reduce图解。

在这里插入图片描述

                                                                                       Map阶段
1、InputFormat

        首先,读取数据组件InputFormat(默认的是TextInputFormat)会通过getSplits的方法对输入目录中的文件信息逻辑切片,有多少个splits,就对应的启动多少个MapTask,split与block的关系是默认的一对一关系,将输入文件切分后,通过Recordreader对象(默认的是LineRedocrdReader)进行读取,将读取的值返回给map

FileInputFormat的切片机制:
A. 简单地按照文件的内容长度进行切片
B. 切片大小,默认等于block大小
C. 切片时不考虑数据集整体,而是逐个针对每一个文件单独切片

2、MapTask阶段

        map读取split切分后返回的<key,value>的值,执行自己的逻辑代码,读取一行,调用一次RecordReader,处理完毕后的结果通过context.write的方法进行数据收集,把数据集放到一个collect的容器中,进行下一步的处理.

3、分区

        在map端收集到的数据,会先对其进行分区处理,默认是对key hash后的值对reduce task数量取模后的值,这样做是为了平衡reduce的处理能力,分区过后,会将分区后的信息,以及数据信息写入到内存中,内存中的这块区域叫做环形缓冲区,通过批量的收集数据来减少磁盘对IO的影响.

         环形缓冲区其实就是一个数组,数组中存放着key,value的序列化数据和key,value的元数据信息,包括partition的起始位置,value的起始位置,以及value的长度.
         环形缓冲区的默认大小是100M,当map的输出结果很多的时候,很可能会撑爆内存,在一定条件下将缓冲区中的数据临时写入磁盘,然后重新利用这块缓冲区继续读取数据,这个过程叫做spill(溢写),缓冲区有个默认的比例:当溢写线程启动后,会锁定80M的内存,执行溢写过程,空出来的20M会继续执行给内存中写数据,一直以这个比例循环的执行

4、排序

         溢写启动后,会将80M的数据内的key进行排序,通过key的序列化字节默认的进行排序

序列化:把结构化的对象转化为字节流

反序列化:是序列化的逆过程,把字节流对象转化为对象

排序: return thisValue < thatValue ? -1 : (thisValue == thatValue ? 0 : 1); #this代表当前对象o1,that代表传参对象o2

返回正数的话,当前对象(调用compareTo方法的对象o1)要排在比较对象(compareTo传参对象o2)后面,返回负数的话,放在前面。

5、规约(是对mapreduce的优化,不影响任何结构,减少网络传输,默认可以省略)

         每次溢写会在磁盘上生成一个临时文件(写之前判断是否有combiner),如果map的输出结果真的很大,有多次这样的溢写发生,磁盘上相应的就会有多个临时文件存在。当整个数据处理结束之后开始对磁盘中的临时文件进行merge合并,因为最终的文件只有一个,写入磁盘,并且为这个文件提供了一个索引文件,以记录每个reduce对应数据的偏移量。

                                                                                       Reduce阶段

在这里插入图片描述

6、分组
在分组之前会先有copy(拉取数据)与sort(全局的排序)两个阶段
       copy阶段包含一个eventFetcher来获取已完成的map列表,由Fetcher线程去copy数据,在此过程中会启动两个merge线程,分别为inMemoryMerger和onDiskMerger,分别将内存中的数据merge到磁盘和将磁盘中的数据进行merge。

merge有三种形式:内存到内存;内存到磁盘;磁盘到磁盘。
默认的第一种方式不会启动当内存中的数据量到达一定阈值,就启动内存到磁盘的merge。与map 端类似,这也是溢写的过程,这个过程中如果你设置有Combiner,也是会启用的,然后在磁盘中生成了众多的溢写文件。第二种merge方式一直在运行,直到没有map端的数据时才结束,然后启动第三种磁盘到磁盘的merge方式生成最终的文件。

      把分散的数据合并成一个大的数据后,还会再对合并后的数据排序。
7、ReduceTask阶段
       对排序后的键值对调用reduce方法,键相等的键值对调用一次reduce方法,
8、TextOutPutFormat
       每次调用会产生零个或者多个键值对,最后把这些输出的键值对写入到HDFS文件中。

三、MapReduce的入门案例(word count)

       单词统计的数据

在这里插入图片描述
数据上传到HDFS上

在这里插入图片描述
编写WordCountRunner 代码

Driver代码

package wordcount;

import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.io.*;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

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

        job.setJarByClass(WordCountRunner.class);
        job.setInputFormatClass(TextInputFormat.class);
        TextInputFormat.addInputPath(job,new Path("hdfs://hadoop01:9000/wordcount/wordcount.txt"));

        job.setMapperClass(WordCountMap.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(LongWritable.class);

        job.setReducerClass(WordCountReduce.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(LongWritable.class);

        job.setOutputFormatClass(TextOutputFormat.class);
        Path path = new Path("hdfs://hadoop01:9000/wordcount/output");
        TextOutputFormat.setOutputPath(job,path);
        //如果存在输出文件就将其删除
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop01:9000"), conf, "root");
        if(fileSystem.exists(path)){
            fileSystem.delete(path,true);
        }

        boolean b = job.waitForCompletion(true);
        System.exit(b?0:1);
    }
}

Map代码

package wordcount;

import org.apache.hadoop.io.*;
import org.apache.hadoop.mapreduce.Mapper;

import java.io.IOException;

public class WordCountMap extends Mapper<LongWritable,Text,Text,LongWritable> {
    Text text = new Text();
    LongWritable one = new LongWritable();
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        String[] split = value.toString().split("\t");
        for (String word : split) {
            text.set(word);
            one.set(1);
            context.write(text,one);
        }
    }
}

reduce代码

package wordcount;

import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.io.*;

import java.io.IOException;

public class WordCountReduce extends Reducer<Text,LongWritable,Text,LongWritable>{
    @Override
    protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
        long count = 0;
        for (LongWritable value : values) {
            count+=value.get();
        }
        context.write(key,new LongWritable(count));
    }
}

将项目打包到hadoop中以jar包的方式运行
在这里插入图片描述
控制台输出如下
在这里插入图片描述
会在target目录下生成jar包
在这里插入图片描述
将jar包丢到$HADOOP_HOME$/share/hadoop/mapreduce 下面
在这里插入图片描述
执行hadoop jar + jar包全名+wordcountRunner的全路径
在这里插入图片描述
控制台输出map和reduce的进度说明程序执行成功
在这里插入图片描述

我们将结果写出到了hdfs上面的/wordcount/out的输出目录,查看目录内容就会发现下面多了两文件,分别是_SUCCESS和part-r-00000
_SUCCESS 是一个执行成功的标识
part-r-00000存放的是我们执行完毕后的结构
在这里插入图片描述

查看part-r-00000,与我们预期的结果一致
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hadoop是一个开源的分布式计算框架,可用于大数据的存储和处理。它采用了分布式文件系统(HDFS)和分布式计算框架(MapReduce),能够将大数据分割成小的数据块,并在集群中的多台计算机上并行处理这些数据块。 HDFS是Hadoop的分布式文件系统,它将大文件切分为多个数据块,并将这些数据块存储在集群中的多个计算机上。HDFS使用主从架构,其中NameNode负责管理文件系统的元数据,而多个DataNode负责实际存储数据。HDFS具有高容错性,能够自动复制数据块以保证数据的可靠性。 MapReduce是Hadoop的分布式计算框架,它通过将计算任务划分为多个Map和Reduce阶段来进行并行计算。Map阶段将输入数据切分为多个独立的小任务,并在集群中的多个计算机上并行执行。Reduce阶段将Map阶段的输出合并并进行聚合计算。MapReduce具有自动并行化、容错性和可扩展性等优点,能够高效地处理大规模数据集。 在学习Hadoop时,首先要了解Hadoop的核心组件,包括HDFS和MapReduce。然后,需要学习Hadoop的架构和工作原理,理解Hadoop如何实现分布式存储和计算。接下来,需要学习Hadoop的安装和配置,包括在单机和集群环境下的安装和配置过程。此外,还需要学习Hadoop的命令行工具和管理工具,以及Hadoop的API和编程模型。 在实际使用Hadoop时,需要掌握Hadoop的常用操作和管理技巧,如如何上传和下载文件、如何执行MapReduce作业、如何监控和管理Hadoop集群等。同时,需要学习Hadoop的优化技术和调优方法,以提高Hadoop集群的性能和效率。 总之,对于Hadoop的学习,除了理解其基础知识和工作原理外,还需要熟悉其常用操作和管理技巧,以及灵活运用Hadoop来解决实际的大数据问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值