MapReduce过程知识点总结

MapReduce

简述mapreduce的整个流程

map端

在这里插入图片描述

MapTask 工作过程

  • Read阶段
  • Map阶段
  • Collect阶段
  • Spill阶段
  • Combine阶段
  1. 由程序内的InputFormat来读取外部的数据,调用RecordReader的read方法来读取并,返回(k,v)键值对
  2. 读取的(k,v)键值对,传送给map()方法,作为其传入参数来执行用户自定义的map逻辑。
  3. context.write方法被调用时,outputcollector组件会将map()方法的输出结果写入到环形缓冲区
  4. 环形缓冲区就是一个环形数组,后端不断接收数据的同时,前端不断的溢出数据,长度用完后读取的新数据再从前端开始覆盖。这个缓冲区的默认size=100M,可以通过MR.SORT.MB配置
  5. spiller组件会从环形缓冲区溢出文件,这个过程会按照定义的partitioner分区(默认的是hashpartition),并且按照key.compareTo进行排序,如果有combiner也会执行combiner。spiller的不断工作,会溢出形成很多小文件(默认达到设置的80%时),会在本地创建溢出文件
  6. 小文件执行merge(合并),形成分区且区内排序
  7. Reduce会根据自己的分区,去所有map task中读取相对应的数据

reduce端

在这里插入图片描述
Reduce Task工作过程

  • Copy阶段
  • Merge阶段
  • Sort阶段
  • Reduce阶段
  • Write阶段
  1. Reduce会从个个MapTask上远程复制一片数据,并针对某一片数据,如果大小超过一定的阈值,则会写到磁盘上,否则直接放到内存中。
  2. 通过GroupingComparator()分辨同一组的数据,把他们发送给reduce(k, iterator)方法(多个数据合成一组时,只取其中第一个key)
  3. 调用context.write方法,会让OutputFormat调用RecordWriter的write()方法将处理结果写入到数据仓库,每一个maptask对应一个分区文件。

shuffle机制

MapReduce工作过程中,Map阶段处理的的数据如何传递给Reduce阶段,shuffle会将MapTask输出的处理结果数据分发给ReduceTask,并在分发的过程中,对数据按照key进行分区和排序。

小文件问题

  1. 小文件处理的弊端:
    • 增加map的开销,每一个分片都要执行一次map任务
    • 增加作业的寻址速度
    • 需要记录小文件的元数据,造成namenode内存浪费
  2. 解决方法
    • 尽量避免小文件,将多个小文件事先合成一个顺序文件:将文件名作为key,将文件内容作为value
    • 如果HDFS中有大批量的小文件,CombineFileInputFormat将多个小文件打包到一个分片中。
    • 使用Hadoop自带的archive工具,主要减少namenode的负载

shuffle机制的缺陷

数据传输的IO问题:

  1. 每一个map可能会有多个spill文件需要写入磁盘,产生较多的磁盘IO
  2. 数据量很小,但是map和reduce任务很多时,产生较多得到网络IO

Combiner函数何时被使用

  1. Map端溢出spill文件后,进行分区排序后,会执行combiner函数。
  2. 多个spill文件合并成一个大文件时,会使用
  3. 在Reduce任务端,复制map输出,在合并后溢出到磁盘时,也会执行combiner函数

MapReduce 执行速度太慢,怎么办?

  1. 自定义分区函数,让key值较为均匀的分布在Reduce上
  2. 对map端进行压缩处理
  3. 使用combiner函数

reduce如何知道从那台机子上获取map的输出?

(MRAppMaster:任务调度和监控)
在Map和Reduce中间有一个MRAppMaster负责协调。MRAppMaster负责任务调度和监控,map结束会通知MRAppMaster,Reduce也会定期去询问MRAppMaster以便获取map输出的位置。

MapReduce如何性能调优?

有四个阶段可以进行性能调优:

  • 数据输入阶段
    1. 小文件问题,产生很多map任务,任务的装载比较耗时,从而导致MapReduce运行速度较慢,可以采用CombineTextInputFormat来作为输入,来解决输入端大量的小文件场景
  • Map阶段
    1. 减少溢写(spill)次数:通过调整io.sort.mb及sort.spiil.percent参数值,增大触发spiil内存上限,减少spill次数,从而缩短磁盘的I/O
    2. 减少合并(merge)次数:通过调整io.sort.factor参数,增大merge的文件数目,减少merge的次数,从而缩短mr处理时间
    3. 在map之后,不影响业务逻辑前提下,先进行combine处理,减少I/O
  • Reduce阶段
    1. 合理设置map和reduce数:不能太少,也不能太多,太少导致task等待,延长处理时间;太多,导致map和reduce任务间竞争资源,造成处理超时等错误
    2. 设置map和reduce共存:调整slowstart.completedmaps参数,使map运行到一定程度后,reduce也开始运行,减少reduce的等待时间。
    3. 规避使用reduce:因为reduce在用于连接数据集的时候会产生大量的网络消耗。通过将MapReduce参数setNumReduceTasks设置为0来创建一个只有map的作业。
    4. 合理设置reduce端的buffer:默认情况下,当数据达到一定的阈值之后,buffer中的数据就会写入到磁盘,然后reduce从磁盘中进行读取所有数据。buffer和reduce是没有直接关联的,中间多一个写磁盘———>都磁盘的过程,既然有这个弊端,那么可以通过设置参数使buffer中的一部分数据直接输送到reduce,从而减少I/O开销。
  • Shuffle阶段
    1. Shuffle阶段主要就是shuffle过程中尽量多的提供内存空间,防止内存溢出 参数mapred.child.java.opts来设置。
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值