Hadoop-MapReduce框架技术

MapReduce是用于数据处理的一种编程模型,简单但足够强大,专门为并行处理大数据而设计。

解决问题的思路就是把一个应用程序分解为许多的分布在各个计算节点的并行的计算指令进行运行。

源自于谷歌的MapReduce论文。海量数据离线处理,易开发,易运行,不适合实时流式计算。

详细关于YARN的MapReduce见:https://mp.csdn.net/postedit/82424154

MapReduce1.x的架构:

MapReduce2.x的架构:

MapReduce2.x编程模型

MapReduce采用“分而治之”的思想。将HDFS上海量数据切分成为若干块,将每块的数据分给集群上的节点进行计算。然后通过整合各节点的中间结果,得到最终的结果。

HDFS上默认块的大小要比磁盘默认的大小大的多。其目的是为了最小化寻址开销。如果块设置得足够大,从磁盘传输数据的时间明显大于定位这个块开始位置所需时间。这样,传输一个由多个块组成的文件时间取决于磁盘传输速率。HDFS默认块的大小为128MB。随着磁盘驱动器的进一步发展块的默认大小可以设置的更大。

MapReduce的处理过程分为两个步骤:map阶段(一堆的map task)和reduce阶段(一堆的reduce task)。每个阶段的输入输出都是key-value的形式

key和value的类型可以自行指定。map阶段对切分好的数据进行并行处理,处理结果传输给reduce,

扫描二维码关注公众号,回复: 3240995 查看本文章

由reduce函数完成最后的汇总。

一个MapReduce作业通常包括输入数据、MapReduce程序以及一些配置信息。Hadoop把作业分解为task运行,task分为map任务和reduce任务,在新版本的Hadoop中,这些Task通过资源管理框架进行调度,如果任务失败,MapReduce应用框架会重新运行任务。

作业的输入被划分为固定大小的分片,叫input splits,简称splits,默认情况下每个InputSplit与HFSD中Block大小相同。然后为每一个split分块创建一个map任务,map任务对每一条记录运行用户定义的map函数。划分为split之后,不同配置的机器就可以根据自己的资源及运算能力运行适当的任务,即使是相同配置的机器,最后运行的任务数也往往不等,这样能有效利用整个集群的计算能力。但是split也不已太多,否则会耗费很多时间在创建map任务上,通常而言,按集群Block大小(默认为128M)来划分split是合理的。

注意:所谓的分片知识逻辑上的分片并不需要物理上的划分,分片细节由InputSplitFormat指定。

每个map任务是一个Java进程。

Hadoop会把map任务运行在里数据最近的节点上,最好的情况是直接在数据(split)所在的节点上运行map任务,这样不需要占用带宽,这一优化叫做数据本地优化(data locality optimization)。下图的map选址方案从最优到最次为a,b,c:

Reduce任务通常无法利用本地数据的优化,大多数情况下,reduce的输入都来自集群的其他节点。reduce针对每一个key运行reduce函数之后,输出结果通常保存在HDFS中,并且存储一定的副本数,第一个副本存在运行reduce任务的本地机器,其他副本根据HDFS写入的管道分别写入节点

MapReduce的处理过程

一个复杂的MapReduce任务可以分为若干个Job。每个Job又可以分为Mapper和Reducer两个阶段。这两个阶段对应到代码内就是继承Mapper的内部类和继承Reducer的内部类。继承Mapper的内部类需要实现map函数,继承Reducer的内部类需要实现Reduce函数。Map函数接收一个<key,value>的键值对同时也会输出一个 <key,value> 的键值对。Reduce函数接收一个<key,list of values>(值为所有键为key的value集合,例如: map的输出为<1,1>,<1,2>,<1,3>,<1,4>则reduce的输入为<1,[1,2,3,4]>)同时经过处理后同样会输出<key,value>键值对。MapReduce运行过程的数据流。

=================================================================================

一个案列介绍MapRdeuce流程处理:

这些数据经过以下几个阶段,假设两个节点。

Split  输入拆分:

输入到MapReduce的数据集被划分成固定大小的块叫做 input splits ,是MapReduce中的最先计算单元。

HDFS:blocksize是HDFS中最小的存储单元 128M,

默认情况下,上面两个大小是一一对应的,当然也可以通过手动设置他们的关系。

映射 - Mapping

通常一个map处理一个块。

这是在 map-reduce 程序执行的第一个阶段。在这个阶段中的每个分割的数据被传递给映射函数来产生输出值。在我们的例子中,映射阶段的任务是计算输入分割出现每个单词的数量(更多详细信息有关输入分割在下面给出)并编制以某一形式列表<单词,出现频率>

多个map是并行处理,没有相互依赖关系。

Shuffle重排:MapReduce的核心阶段

Mapper端产生的数据不会直接写入到磁盘,而是先写入到内容,到达一定数量的数据时,才会写入磁盘。这个阶段消耗映射阶段的输出(减少reduce的输入量)。它的任务是合并映射阶段输出的相关记录。

注意,shuffing阶段是将不同节点上的相同键集中到一个节点上,然后划分一个分区中,

方便reduce规约,分区的数量就是Reduce任务运行的数量。

Reducing

在这一阶段,从重排阶段输出值汇总,Reduce函数接收一个<key,list of values>(值为所有键为key的value集合)

这个阶段结合来自重排阶段值,并返回一个输出值。一个ruduce对应一个part-0000X文件。

总之,这一阶段汇总了完整的数据集。

在我们的例子中,这个阶段汇总来自重排阶段的值,计算每个单词出现次数的总和。

附:MapReduce之Combiner

相当于在map所在的节点(端)做了本地的reduce操作,减少Map task输出量及数据网络传输量,

会就减少reduce段的task任务,提高效率

适用于:求和,次数。

 

 

详细的整个过程

  • 映射的任务是为每个分割创建在分割每条记录执行映射的函数。

  • 有多个分割是好处的, 因为处理一个分割使用的时间相比整个输入的处理的时间要少, 当分割比较小时,处理负载平衡是比较好的,因为我们正在并行地处理分割。

  • 然而,也不希望分割的规模太小。当分割太小,管理分割和映射创建任务的超负荷开始逐步控制总的作业执行时间。

  • 对于大多数作业,最好是分割成大小等于一个HDFS块的大小(这是128 MB,默认情况下)。

  • map任务执行结果到输出写入到本地磁盘的各个节点上,而不是HDFS。

  • 之所以选择本地磁盘而不是HDFS是因为,避免复制其中发生 HDFS 存储操作。

  • 映射输出是由减少任务处理以产生最终的输出中间输出。

  • 一旦任务完成,映射输出可以扔掉了。所以,复制并将其存储在HDFS变得大材小用。

  • 在节点故障的映射输出之前,由 reduce 任务消耗,Hadoop 重新运行另一个节点在映射上的任务,并重新创建的映射输出。

  • 减少任务不会在数据局部性的概念上工作。每个map任务的输出被供给到 reduce 任务。映射输出被传输至计算机,其中 reduce 任务正在运行。
  • 在此机器输出合并,然后传递到用户定义的 reduce 函数。
  • 不像到映射输出,reduce输出存储在HDFS(第一个副本被存储在本地节点上,其他副本被存储于偏离机架的节点)。因此,写入 reduce 输出

案列实现源码:https://blog.csdn.net/qq_25948717/article/details/81031676

猜你喜欢

转载自blog.csdn.net/qq_25948717/article/details/81950083