我要进大厂之大数据MapReduce知识点(1)
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)的更多相关文章
- 我要进大厂之大数据MapReduce知识点(2)
01 我们一起学大数据 今天老刘分享的是MapReduce知识点的第二部分,在第一部分中基本把MapReduce的工作流程讲述清楚了,现在就是对MapReduce零零散散的知识点进行总结,这次的内容大 ...
- 我要进大厂之大数据ZooKeeper知识点(2)
01 我们一起学大数据 接下来是大数据ZooKeeper的比较偏架构的部分,会有一点难度,老刘也花了好长时间理解和背下来,希望对想学大数据的同学有帮助,也特别希望能够得到大佬的批评和指点. 02 知识 ...
- 我要进大厂之大数据ZooKeeper知识点(1)
01 让我们一起学大数据 老刘又回来啦!在实验室师兄师姐都找完工作之后,在结束各种科研工作之后,老刘现在也要为找工作而努力了,要开始大数据各个知识点的复习总结了.老刘会分享出自己的知识点总结,一是希望 ...
- 我要进大厂之大数据Hadoop HDFS知识点(1)
01 我们一起学大数据 老刘今天开始了大数据Hadoop知识点的复习,Hadoop包含三个模块,这次先分享出Hadoop中的HDFS模块的基础知识点,也算是对今天复习的内容进行一次总结,希望能够给想学 ...
- 我要进大厂之大数据Hadoop HDFS知识点(2)
01 我们一起学大数据 老刘继续分享出Hadoop中的HDFS模块的一些高级知识点,也算是对今天复习的HDFS内容进行一次总结,希望能够给想学大数据的同学一点帮助,也希望能够得到大佬们的批评和指点! ...
- 大数据 --> MapReduce原理与设计思想
MapReduce原理与设计思想 简单解释 MapReduce 算法 一个有趣的例子:你想数出一摞牌中有多少张黑桃.直观方式是一张一张检查并且数出有多少张是黑桃? MapReduce方法则是: 给在座 ...
- 大数据核心知识点:Hbase、Spark、Hive、MapReduce概念理解,特点及机制
今天,上海尚学堂大数据培训班毕业的一位学生去参加易普软件公司面试,应聘的职位是大数据开发.面试官问了他10个问题,主要集中在Hbase.Spark.Hive和MapReduce上,基础概念.特点.应用 ...
- 大白话详解大数据hive知识点,老刘真的很用心(2)
前言:老刘不敢说写的有多好,但敢保证尽量用大白话把自己复习的内容详细解释出来,拒绝资料上的生搬硬套,做到有自己的了解! 1. hive知识点(2) 第12点:hive分桶表 hive知识点主要偏实践, ...
- 大白话详解大数据hive知识点,老刘真的很用心(3)
前言:老刘不敢说写的有多好,但敢保证尽量用大白话把自己复习的内容详细解释出来,拒绝资料上的生搬硬套,做到有自己的了解! 1. hive知识点(3) 从这篇文章开始决定进行一些改变,老刘在博客上主要分享 ...
随机推荐
- Python包安装及使用指南
这里长期更新一些Python第三方包的安装教程,以及使用教程... Pygame 安装教程: Windows: 首先,查看已安装的Python版本:访问https://www.lfd.uci.edu/ ...
- B树摘要
BTree 以下内容是根据<算法导论>摘要而来,由于国内书籍对B树的定义是以阶来定义,而<算法导论>中使用的是最小度来定义,并且节点中关键字个数也不相同,在翻看网上博客时,产生 ...
- rsync 守护进程模式搭建 与常见报错
守护进程模式搭建 1.环境准备 2.安装rsync(做备份的服务器都安装) [root@backup ~]# yum install -y rsync 3.服务端配置 [root@backup ~]# ...
- NMS总结
目录 NMS总结 一. NMS 二. Soft-NMS 三. IOU-Guided NMS 四. Softer-NMS 五. DIOU-NMS 六. 总结 NMS总结 一. NMS 目标检测:同一个类 ...
- GO-字符串处理Stings包
目录 常用的字符串处理函数 (1) Contains (2) Join (3) Index (4) Repeat (5) Replace (6) Split (7) Trim (8) Fields 字 ...
- 执行 vue inspect > output.js 报错,无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\vue.ps1,因为在此系统中禁止执行脚本
无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\vue.ps1,因为在此系统中禁止执行脚本.有关详细信息,请参阅 "get-help ab ...
- 【算法】HashMap相关要点记录
在刷leetcode的算法题时,HashMap需要大量使用,而且也是面试的高频问题.这里记录了HashMap一些增.删.改.查的实现细节和时间复杂度,罗列了一些比较有用的方法,以及其它的一些细节. 1 ...
- DevOps 视角的前后端分离与实战
本文作者:CODING - 廖红坤 前言 随着微前端.微服务等技术理念和架构的蓬勃发展,我们已经没必要去讨论为什么要前后端分离这种话题,前后端分离已成为互联网项目开发的标准模式.前后端在各自的领域发展 ...
- Go语言反射(reflect)及应用
Go语言反射(reflect)及应用 基本原理及应用场景 在编译时不知道类型的情况下,可更新变量.在运行时查看值.调用方法以及直接对它们的布局进行操作,这种机制被称为反射. 具体的应用场景大概如下: ...
- MySQL安装及安装问题解答(二)
在安装过程中难免会有一些异常情况出现,笔者对一部分异常情况做出解答以供参考 1.MySQL未能成功启动 在输入net start mysql后提示 MySQL 服务正在启动, MySQL 服务无法启动 ...