MapReduce简介

MapReduce简介

  • MapReduce优点
  • MapReduce缺点
  • MapReduce核心思想
  • 切片机制
    • FileInputFormat切片机制
    • CombineTextInputFormat切片机制
  • MapTask工作机制
  • Shuffle机制
    • Combiner合并排序
  • Reduce Task工作机制
    • ReduceTask的个数决定了有几个结果文件
  • MapReduce数据压缩
    • 压缩特性运用得当能提高性能,但运用不当也可能降低性能,基本原则:
    • MapReduce支持的压缩编码
    • 可以使用压缩的位置
  • MapReduce调优
    • 数据输入
    • Map阶段
    • Reduce阶段
    • 数据倾斜问题
      • 使用Map join代替Reduce join

MapReduce优点

易于编程、良好的扩展性、高容错、适合PB级以上海量数据的离线处理。

MapReduce缺点

不擅长实时计算、不擅长流式计算、不擅长DAG(有向图)计算。

MapReduce核心思想

1.第一个阶段的map task并发实例,完全并行运行,互不相干。
2.第二个阶段的reduce task并发实例互不相干,但是他们的数据依赖于上一个阶段的所有map task并发实例的输出。
3.MapReduce编程模型只能包含一个map阶段和一个reduce阶段,如果用户的业务逻辑非常复杂,那就只能多个mapreduce程序,串行运行。

切片机制

FileInputFormat切片机制

每次切片时,都要判断切完剩下的部分是否大于块的1.1倍,不大于1.1倍就划分一块切片。

CombineTextInputFormat切片机制

将输入目录下所有文件大小,依次和设置的setMaxInputSplitSize值比较,如果不大于设置的最大值,逻辑上划分一个虚拟存储块。如果输入文件大于设置的最大值且大于两倍,那么以最大值切割一个虚拟存储块;当剩余数据大小超过设置的最大值且不大于最大值2倍,此时将文件均分成2个虚拟存储块(防止出现太小切片)。之后判断虚拟存储的文件大小是否大于setMaxInputSplitSize值,大于等于则单独形成一个切片,如果不大于则跟下一个虚拟存储块进行合并,共同形成一个切片。

MapTask工作机制

一个job的map阶段MapTask并行度(个数),由客户端提交job时的切片个数决定。
MapReduce简介_第1张图片
Read阶段:Map Task通过用户编写的RecordReader,从输入InputSplit中解析出一个个key/value。
Map阶段:该节点主要是将解析出的key/value交给用户编写map()函数处理,并产生一系列新的key/value。
Collect收集阶段:在用户编写map()函数中,当数据处理完成后,一般会调用context.write,context.write底层 OutputCollector.collect()输出结果。在该函数内部,会将生成的key/value分区(调用Partitioner),并写入一个环形内存缓冲区中。
Spill阶段:即“溢写”,当环形缓冲区满后,MapReduce会将数据写到本地磁盘上,生成一个临时文件。需要注意的是,将数据写入本地磁盘之前,先要对数据进行一次本地排序,并在必要时对数据进行合并等操作。
Combine阶段:当所有数据处理完成后,MapTask对所有临时文件进行一次合并,以确保最终只会生成一个数据文件。
在进行文件合并过程中,MapTask以分区为单位进行合并。对于某个分区,它将采用多轮递归合并的方式。每轮合并io.sort.factor(默认100)个文件,并将产生的文件重新加入待合并列表中。对文件排序后,重复以上过程,直到最终得到一个大文件。

Shuffle机制

系统执行排序的过程(即将mapper输出作为输入传给reducer)称为shuffle。
MapReduce简介_第2张图片
对于Map Task,它会将处理的结果暂时放到一个缓冲区中,当缓冲区使用率达到一定阈值后,再对缓冲区中的数据进行一次排序,并将这些有序数据写到磁盘上,而当数据处理完毕后,它会对磁盘上所有文件进行一次合并,以将这些文件合并成一个大的有序文件。
对于Reduce Task,它从每个Map Task上远程拷贝相应的数据文件,如果文件大小超过一定阈值,则放到磁盘上,否则放到内存中。如果磁盘上文件数目达到一定阈值,则进行一次合并以生成一个更大文件;如果内存中文件大小或者数目超过一定阈值,则进行一次合并后将数据写到磁盘上。当所有数据拷贝完毕后,Reduce Task统一对内存和磁盘上的所有数据进行一次合并。

Combiner合并排序

1.Combiner是MR程序中Mapper和Reducer之外的一种组件。
2.Combiner组件的父类就是Reducer。
3.Combiner和reducer的区别在于运行的位置:
  Combiner是在每一个Map Task所在的节点运行;
  Reducer是接收全局所有Mapper的输出结果;
4.Combiner的意义就是对每一个maptask的输出进行局部汇总,以减小网络传输量。

Reduce Task工作机制

MapReduce简介_第3张图片
Copy阶段:ReduceTask从各个MapTask上远程拷贝一片数据,并针对某一片数据,如果其大小超过一定阈值,则写到磁盘上,否则直接放到内存中。
Merge阶段:在远程拷贝数据的同时,ReduceTask启动了两个后台线程对内存和磁盘上的文件进行合并,以防止内存使用过多或磁盘上文件过多。
Sort阶段:按照MapReduce语义,用户编写reduce()函数输入数据是按key进行聚集的一组数据。为了将key相同的数据聚在一起,Hadoop采用了基于排序的策略。由于各个MapTask已经实现对自己的处理结果进行了局部排序,因此,ReduceTask只需对所有数据进行一次归并排序即可。
Reduce阶段:reduce()函数将计算结果写到HDFS上。

ReduceTask的个数决定了有几个结果文件

Reducetask数量的决定是可以手动设置。
如果ReduceTask的数量 > getPartition(分区)的结果数,则会多产生几个空的输出文件;
如果1 < ReduceTask的数量 < getPartition的结果数,则有一部分分区数据无处安放,会Exception;
如果ReduceTask的数量 = 1,则不管mapTask端输出多少个分区文件,最终结果都交给这一个ReduceTask,最终也就只会产生一个结果文件。

MapReduce数据压缩

压缩技术能够有效减少底层存储系统(HDFS)读写字节数,提高了网络带宽和磁盘空间的效率。

压缩特性运用得当能提高性能,但运用不当也可能降低性能,基本原则:

运算密集型的job,少用压缩
IO密集型的job,多用压缩

MapReduce支持的压缩编码

压缩格式 工具 算法 文件扩展名 是否可切分
DEFLATE DEFLATE .deflate
Gzip gzip DEFLATE .gz
bzip2 bzip2 bzip2 .bz2
LZO lzop LZO .lzo
LZ4 LZ4 .lz4 否(不确定)
Snappy Snappy .snappy

可以使用压缩的位置

MapReduce简介_第4张图片
当map任务输出的中间数据量很大时,应考虑在此阶段采用压缩技术,能显著改善内部数据Shuffle过程,而Shuffle过程在Hadoop处理过程中是资源消耗最多的环节。可用于压缩mapper输出的快速编解码器包括LZO、LZ4或者Snappy。
压缩reducer输出能够减少要存储的数据量,因此降低所需的磁盘空间。

MapReduce调优

MapReduce优化方法主要从六个方面考虑:数据输入、Map阶段、Reduce阶段、IO传输、数据倾斜问题和常用的调优参数。

数据输入

合并小文件。

Map阶段

1.减少溢写(spill)次数:通过调整环形缓冲区的大小,增大触发spill的内存上限,减少spill次数,从而减少磁盘IO。
2.减少合并(merge)次数:通过调整io.sort.factor参数,增大merge的文件数目,减少merge的次数,从而缩短MR处理时间。
3.在map之后,不影响业务逻辑前提下,先进行Combine处理,减少 I/O。

Reduce阶段

1.合理设置maptask和reducetask数:两个都不能设置太少,也不能设置太多。太少,会导致task等待,延长处理时间;太多,会导致 map、reduce任务间竞争资源,造成处理超时等错误。
2.设置map、reduce共存:调整slowstart.completedmaps参数,使map运行到一定程度后,reduce也开始运行,减少reduce的等待时间。
3.合理设置reduce端的buffer:默认情况下,数据达到一个阈值的时候,buffer中的数据就会写入磁盘,然后reduce会从磁盘中获得所有的数据。也就是说,buffer和reduce是没有直接关联的,中间多个一个写磁盘->读磁盘的过程,既然有这个弊端,那么就可以通过参数来配置,使得buffer中的一部分数据可以直接输送到reduce,从而减少IO开销:mapred.job.reduce.input.buffer.percent,默认为0.0。当值大于0的时候,会保留指定比例的内存读buffer中的数据直接拿给reduce使用。这样一来,设置buffer需要内存,读取数据需要内存,reduce计算也要内存,所以要根据作业的运行情况进行调整。

数据倾斜问题

使用自定义分区、使用Combine合并,如果有join尽量使用Map join。

使用Map join代替Reduce join

原因:Reduce join方式中,合并的操作是在reduce阶段完成,reduce端的处理压力太大,map节点的运算负载则很低,资源利用率不高,且在reduce阶段极易产生数据倾斜(同一个reduce接收到的数据量很大)。

你可能感兴趣的:(hadoop,mapreduce)