01 我们一起学大数据

老刘今天分享的是大数据Hadoop框架中的分布式计算MapReduce模块,MapReduce知识点有很多,大家需要耐心看,用心记,这次先分享出MapReduce的第一部分。老刘这次根据自学的资料分享出这些知识点,一是希望能够帮助对大数据感兴趣的同学,二是希望得到大佬的批评和指导。

02 MapReduce知识点

第1点:MapReduce的概念

MapReduce,它是一个分布式的计算框架,并且采用了一种分而治之的思想。从单词上就可以看出MapReduce由两个阶段组成:

Map阶段(把大任务切分成一个个小的任务)

Reduce阶段(汇总一个个小任务的结果)

那什么是分而治之呢?

比如一个复杂、计算量大、耗时长的的任务,暂且称为“大任务”;如果此时使用单台服务器无法计算或较短时间内计算没有出结果时,就可以将这个大任务切分成一个个小的任务,小任务可以分别在不同的服务器上并行执行,最终再汇总每个小任务的结果。


第2点:Map阶段的介绍

map阶段有一个关键的map()函数,这个map()函数的输入是(k,v)键值对,输出也是一系列的(k,v)键值对,最后将输出结果写入到本地磁盘。

第3点:Reduce阶段的介绍

reduce阶段有一个关键的reduce()函数,这个reduce()函数的输入也是键值对(也就是map输出的键值对),输出也是一系列(k,v)键值对,结果最后会写入HDFS中。

将第2点和第3点的介绍总结成一张图,如下:


第4点:MapReduce编程

讲完上述一些概念后,老刘当时处于似懂非懂的状态,于是就看了资料给出的编程实例,搞懂这个实例的原理和每行代码后,当时就感觉豁然开朗了,贼开心!

我们以MapReduce的词频统计为例:统计一批英文文章当中,每个单词出现的总次数。

MapReduce词频统计原理图

图片有点模糊,大家将就着看看,先分享出map端和reduce端的关键代码,完整代码分享在最后面。

在map端:

String line = value.toString();
//按照\t进行分割,得到当前行所有单词
String[] words = line.split("\t"); for (String word : words) {
//将每个单词word变成键值对形式(word, 1)输出出去
//同样,输出前,要将kout, vout包装成对应的可序列化类型,如String对应Text,int对应IntWritable
context.write(new Text(word), new IntWritable(1));
}

在reduce端:

//定义变量,用于累计当前单词出现的次数
int sum = 0; for (IntWritable count : values) {
//从count中获得值,累加到sum中
sum += count.get();
}
//将单词、单词次数,分别作为键值对,输出
context.write(key, new IntWritable(sum));// 输出最终结果

关于代码,老刘想说的是MapReduce中每个参数都要搞清楚!上面只是核心代码,虽然看起来很简单,但是还有很多细节,各种参数,都要仔细搞清楚!

接下来就来好好说说这个流程,

在Map阶段:

假设MR的输入文件有三个block:block1,block2,block3,每一个block对应一个split分片,每一个split对应一个map任务(map task)。

看上面这个图,一共有3个map任务(map1,map2,map3),这3个任务的逻辑大致上相同的,就直接讲讲第一个就行了。

map1读取block1的数据,一次读取block1的一行数据,将当前所读行的行首相对于当前block开始处的字节偏移量作为key(0),当前行的内容作为value。

然后键值对会作为map()的参数传入,调用map()。

在map()函数中,就会根据各种需求写代码,如果是单词统计,就会将value当前行的内容按照空格切分,得到三个单词Dear,Bear,River。

在将每个单词变成键值对,输出出去得到(Dear, 1) | (Bear, 1) | (River, 1)。

最终结果写入map任务所在节点的本地磁盘中(这里面还有很多细节,会涉及shuffle知识点,在这篇文章的后面会慢慢展开)。

block的第一行的数据被处理完后,接着处理第二行,原理和上面的一样。当map任务将当前block中所有的数据全部处理完后,此map任务即运行结束。

在Reduce阶段:

reduce任务(即reduce task)的个数由自己写的程序指定的,在main()内写job.setNumReduceTasks(4),就可以指定reduce任务是4个(reduce1、reduce2、reduce3、reduce4)。

每一个reduce任务的逻辑差不多,所以就拿第一个reduce任务做分析。

map1任务完成后,reduce1通过http网络,连接到map1,将map1输出结果中属于reduce1的分区的数据(采用的是默认哈希分区),通过网络获取到reduce1端,同样也是这样连接到map2、map3获取结果。

最终reduce1端获得4个(Dear, 1)键值对;由于他们的key键是相同的,它们分到同一组;这4个(Dear, 1)键值对,在转换成[Dear, Iterable(1, 1, 1, )],作为两个参数传入reduce()。

在reduce()内部,计算Dear的总数为4,并将(Dear, 4)作为键值对输出,每个reduce任务最终输出文件将写入到HDFS。这里也会涉及到shuffle。

大致就是这样的流程,代码写完后,生成Jar包,然后在Hadoop集群中运行。

讲完这个实例,老刘有句话说,MapReduce实例有很多很多,这只是其中一个,大家可以自己找找更多的实例,老刘继续分享出MapReduce编程:数据清洗,搜索用户次数两个例子的相关代码,放在最后,大家可以去看看。

第5点:shuffle

这是个重点,相当重要的重点。shuff主要指的是map端的输出作为reduce端输入的过程。它的中文意思是洗牌。

先给出它的细节图:

分区用到了分区器,默认分区器是HashPartitioner,代码如下:

public class HashPartitioner<K2, V2> implements Partitioner<K2, V2> {

  public void configure(JobConf job) {}

  /** Use {@link Object#hashCode()} to partition. */
public int getPartition(K2 key, V2 value,
int numReduceTasks) {
return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
}
}

接下来说说具体流程,

在map端:

1、每个map任务都有一个对应的环形内存缓冲区;输出的是kv对,先写入到环形缓冲区(默认大小100M),当内容占据80%缓冲区空间后,由一个后台线程将缓冲区中的数据溢出写到一个磁盘文件。

2、在溢出写的过程中,map任务继续向环形缓冲区写入数据;但是若写入速度大于溢出写的速度,最终造成100m占满后,map任务会暂停向环形缓冲区中写数据的过程;只执行溢出写的过程;直到环形缓冲区的数据全部溢出写到磁盘,才恢复向缓冲区写入。

3、后台线程溢写磁盘过程,有以下几个步骤:

① 先对每个溢写的kv对做分区;分区的个数由MR程序的reduce任务数决定;默认使用HashPartitioner计算当前kv对属于哪个分区;计算公式为(key.hashCode() & Integer.MAX_VALUE) % numReduceTasks

② 每个分区中,根据kv对的key做内存中排序;

③ 若设置了map端本地聚合combiner,则对每个分区中,排好序的数据做combine操作;

④ 若设置了对map输出压缩的功能,会对溢写数据压缩;

注意:第二步中的排序,老刘看了很多资料上都没讲,就自行搜索了一些资料,该排序操作属于Hadoop的默认行为。任何应用程序中的数据均会被排序,而不管逻辑上是否需要。

排序分类有5个分类:部分排序、全排序、利用分区器实现全部排序、辅助排序、二次排序,具体概念就不阐述了,自行搜索吧!

4、随着不断的向环形缓冲区中写入数据,会多次触发溢写(每当环形缓冲区写满100m),本地磁盘最终会生成多个溢出文件。

5、在map task完成之前,所有溢出文件会被合并成一个大的溢出文件;并且是已分区、已排序的输出文件。

这里,有一些小细节,大家记一下:

在合并溢写文件时,如果至少有3个溢写文件,并且设置了map端combine的话,会在合并的过程中触发combine操作;

但是若只有2个或1个溢写文件,则不触发combine操作(因为combine操作,本质上是一个reduce,需要启动JVM虚拟机,有一定的开销)

在reduce端:

1、reduce task会在每个map task运行完成后,通过HTTP获得map task输出中,属于自己的分区数据(许多kv对)。

2、如果map输出数据比较小,先保存在reduce的jvm内存中,否则直接写入Reduce磁盘。

3、一旦内存缓冲区达到阈值(默认0.66)或map输出数的阈值(默认1000),则触发归并merge,结果写到本地磁盘。若MR编程指定了combine,在归并过程中会执行combine操作。

4、随着溢出写的文件的增多,后台线程会将它们合并大的、排好序的文件。

5、reduce task将所有map task复制完后,将合并磁盘上所有的溢出文件,默认一次合并10个,最后一批合并,部分数据来自内存,部分来自磁盘上的文件。

6、进入“归并、排序、分组阶段”

7、每组数据调用一次reduce方法

8、最后结果写入到HDFS

03 知识点总结

说实话,今天知识点有点多,刚开始学的时候,有一些东西确实很难理解,但是当你记住它的时候,对以后学习spark、flink真的特别有用,会发现这个模块的很多内容原理大致差不多,请一定要记住今天分享的内容。

最后要说的是MapReduce的编程实例都放在老刘的公众号了,大家感兴趣的可以去看看。

有事,联系公众号:努力的老刘;没事,和老刘一起学大数据。

我要进大厂之大数据MapReduce知识点(1)的更多相关文章

  1. 我要进大厂之大数据MapReduce知识点(2)

    01 我们一起学大数据 今天老刘分享的是MapReduce知识点的第二部分,在第一部分中基本把MapReduce的工作流程讲述清楚了,现在就是对MapReduce零零散散的知识点进行总结,这次的内容大 ...

  2. 我要进大厂之大数据ZooKeeper知识点(2)

    01 我们一起学大数据 接下来是大数据ZooKeeper的比较偏架构的部分,会有一点难度,老刘也花了好长时间理解和背下来,希望对想学大数据的同学有帮助,也特别希望能够得到大佬的批评和指点. 02 知识 ...

  3. 我要进大厂之大数据ZooKeeper知识点(1)

    01 让我们一起学大数据 老刘又回来啦!在实验室师兄师姐都找完工作之后,在结束各种科研工作之后,老刘现在也要为找工作而努力了,要开始大数据各个知识点的复习总结了.老刘会分享出自己的知识点总结,一是希望 ...

  4. 我要进大厂之大数据Hadoop HDFS知识点(1)

    01 我们一起学大数据 老刘今天开始了大数据Hadoop知识点的复习,Hadoop包含三个模块,这次先分享出Hadoop中的HDFS模块的基础知识点,也算是对今天复习的内容进行一次总结,希望能够给想学 ...

  5. 我要进大厂之大数据Hadoop HDFS知识点(2)

    01 我们一起学大数据 老刘继续分享出Hadoop中的HDFS模块的一些高级知识点,也算是对今天复习的HDFS内容进行一次总结,希望能够给想学大数据的同学一点帮助,也希望能够得到大佬们的批评和指点! ...

  6. 大数据 --> MapReduce原理与设计思想

    MapReduce原理与设计思想 简单解释 MapReduce 算法 一个有趣的例子:你想数出一摞牌中有多少张黑桃.直观方式是一张一张检查并且数出有多少张是黑桃? MapReduce方法则是: 给在座 ...

  7. 大数据核心知识点:Hbase、Spark、Hive、MapReduce概念理解,特点及机制

    今天,上海尚学堂大数据培训班毕业的一位学生去参加易普软件公司面试,应聘的职位是大数据开发.面试官问了他10个问题,主要集中在Hbase.Spark.Hive和MapReduce上,基础概念.特点.应用 ...

  8. 大白话详解大数据hive知识点,老刘真的很用心(2)

    前言:老刘不敢说写的有多好,但敢保证尽量用大白话把自己复习的内容详细解释出来,拒绝资料上的生搬硬套,做到有自己的了解! 1. hive知识点(2) 第12点:hive分桶表 hive知识点主要偏实践, ...

  9. 大白话详解大数据hive知识点,老刘真的很用心(3)

    前言:老刘不敢说写的有多好,但敢保证尽量用大白话把自己复习的内容详细解释出来,拒绝资料上的生搬硬套,做到有自己的了解! 1. hive知识点(3) 从这篇文章开始决定进行一些改变,老刘在博客上主要分享 ...

随机推荐

  1. monolog记录日志

    <?php require_once 'vendor/autoload.php'; use Monolog\Formatter\LineFormatter; use Monolog\Logger ...

  2. web功能测试

    web功能测试基础: https://www.cnblogs.com/wz123/p/9680484.html

  3. git -- Authentication failed for 报错如何解决?

    昨天拉代码拉不下来,报这个错误:fatal: Authentication failed for .... 有很多网上的解释是 $  git config --global --replace-all ...

  4. 解析SparkStreaming和Kafka集成的两种方式

    spark streaming是基于微批处理的流式计算引擎,通常是利用spark core或者spark core与spark sql一起来处理数据.在企业实时处理架构中,通常将spark strea ...

  5. SpringMVC异常的处理机制

    SpringMVC异常的处理机制 处理流程图 其本质还是把异常交给SpringMVC框架来处理 系统的dao.service.controller出现异常都通过throws Exception向上抛出 ...

  6. CGANs

    Introducation 1. intruduce the conditional version of GANs, which can be constructed by simply feedi ...

  7. 案例>>>用绝对值的方法打印出菱形

    import java.util.Scanner; public class Test { public static void main(String[] args) { Scanner sc = ...

  8. 数据结构(C++)——顺序表

    顺序表和链表的比较 1.存取方式 顺序表可以随机访问,而链表只能从表头顺序查找.(因此经常查找顺序表某一个元素时,顺序表更适合) 2.逻辑结构与物理结构 顺序表中,逻辑上相邻的元素,其物理存储位置也相 ...

  9. mysql-connector-java各种版本下载地址

    mysql-connector-java下载地址: http://mvnrepository.com/artifact/mysql/mysql-connector-java 目录 1.进去后选择自己的 ...

  10. 【新阁教育】S7.NET+Log4Net+SQLSugar+MySQL搭建Iot平台

    1.搭建西门子S7仿真环境 新阁教育提醒您基于PLCSIM-Advanced搭建西门子S7仿真环境注意事项: 1.通过dotNet工控上位机公众号后台发送PLCSIM-Advanced获取软件 2.安 ...