MapReduce之Map,Reduce,Shuffle,Yarn的机制+流程图

MapReduce详细工作流程之Map阶段
在这里插入图片描述
例如图中所示:

  1. 我们要处理一个200M的文件
  2. 切片: 在client提交之前,我们需要先将文件按照128M每块进行切片
  3. 提交: 提交到本地工作环境过Yarn来处理
  4. 提交时会把每个任务封装成一个job交给Yarn来处理,计算出MapTask数量,每个MapTask并行执行
  5. MapTask中执行Mapper的map方法,需要k,v作为键值对传递给map方法
    1. map方法会进行一系列逻辑操作,执行完成后,最后进行写操作
    2. 需要注意: map方法直接将结果写给reduce的话会制造太多IO操作,失效率变慢,效率降低,因此,map和reduce之间还有一段shuffle操作
  6. 每个MapTask中的map方法处理完相关逻辑后,先通过outputCollector向环形缓冲区写数据,环形缓冲区分为两部分,一部分是写于文件的元数据信息,另一部分是写入文件的真实信息,环形缓冲区默认大小是100M,当缓存容量达到默认大小的80%时,就会触发溢写(spill)

溢写: 这是一个并行的过程,不会占用map线程资源,整个缓冲区都有溢写比例spill.percent
,默认是0.8,如果map线程过于忙碌,同时溢写线程太慢,map()就会暂停执行去等待溢写完成

  1. 在环形缓冲区和溢写各自执行的任务都自行进行归并排序后, 在9-10步之间进行combine合并操作,这样能够减少MapTask的带宽占比,减少网络传输量

Map阶段的进程数要比Reduce阶段的多,所以任务放在Map阶段处理的效率要更高,Map阶段的数据进行合并以后,传递给Reduce的数据就会少很多,同时要注意,Combine的输出K,V要和Reduce的输入K,V类型对应起来.

总结:
整个MapTask阶段分为Read阶段,Map阶段,Collect阶段,溢写(spill)阶段和Combine阶段:

  • Read阶段:MapTask通过用户编写的RecordReader,从输入的InputSplit中解析出一个个的Key/Value
  • Map阶段:将上一步解析出来的Key/Value通过Map()方法逻辑从而产生新的Key/Value
  • Collect阶段:将收集到的所有Key/Value写入环形缓冲区内
  • Spill(溢写)阶段:当环形缓冲区容量使用超过80%后,会将溢出部分数据写入本地磁盘中(写入之间要先进行本地排序)
  • Combine(合并)阶段:结合缓冲区内的以及磁盘中的文件,最后进行合并压缩,减少传输过程中的带宽占比

Mapreduce详细工作流程给之Reduce阶段
在这里插入图片描述
例如上图所示:

  1. 所有的MapTask任务完成以后,会启动相应数量的Reduce Task并将拷贝进来的数据存到磁盘中,进行合并归并排序
  2. 然后将数据传给reduce进行处理,一次读取一组数据
  3. 最后通过outputFormat输出

总结:整个ReduceTask分为Copy阶段,Merge阶段和Sort阶段,reduce阶段

  • Copy阶段:ReduceTask从MapTask上拷贝来的数据进行分析,存放,如果大小超过一定阈值,则写在磁盘上,否则直接存到内存中.
  • Merge阶段: 远程拷贝的同时,ReduceTask启动两个后台线程对内存和磁盘上的文件进行合并,防止内存或磁盘上文件过多
  • Sort阶段: 跟据用户编写的reduce()函数按照Key进行排序,因为Hadoop采用了基于排序的策略,MapTask已经对数据进行了局部排序,此时ReduceTask只需将数据进行归并排序即可.
  • Reduce阶段: reduce()函数计算结果写到HDFS上

Shukkle机制
在这里插入图片描述
Map方法之后Reduce方法之前的数据处理过程称之为Shuffle.Shuffle流程:

  1. MapTask收集map()方法输出的kv对,放入到环形缓冲区内中
  2. 从环形缓冲区不断溢出的本地磁盘文件,可能会溢出多个文件
  3. 多个溢出文件会被合并成大的溢出文件
  4. 合并过程中都要调用Partitioner进行分区和针对Key进行排序
  5. ReduceTask跟据自己的区号,到MapTask的结果分区上去,去取相应数据
  6. ReduceTask将来自不同分区的MapTask结果文件进行归并排序
  7. 最终合并成大文件后,Shuffle过程也就结束了,进入reduce方法

Yarn工作机制
在这里插入图片描述
job提交全过程

1.MR程序提交到客户端所在的节点,YarnRunner向ResourceManager申请一个Application

2.RM将该Application的资源路径和作业id返回给YarnRunner

3.YarnRunner将运行job所需资源提交到HDFS上

4.程序资源提交完毕后,申请运行mrAppMaster

5.RM将用户的请求初始化成一个Task

6.其中一个NodeManager领取到Task任务

7.该NodeManager创建容器Container,并产生MRAppmaster

8.Container从HDFS上拷贝资源到本地

9.MRAppmaster向RM 申请运行MapTask资源

10.RM将运行MapTask任务分配给另外两个NodeManager,另两个NodeManager分别领取任务并创建容器

11.MR向两个接收到任务的NodeManager发送程序启动脚本,这两个NodeManager分别启MapTask,MapTask对数据分区排序

12.MrAppMaster等待所有MapTask运行完毕后,向RM申请容器,运行ReduceTask

13.ReduceTask向MapTask获取相应分区的数据

14.程序运行完毕后,MR会向RM申请注销自己

进度和状态更新:YARN中的任务将其进度和状态(包括counter)返回给应用管理器,客户端每秒(通过mapreduce.client.progressmonitor.pollinterval设置)向应用管理器请求进度更新,展示给用户

作业完成: 除了向应用管理器请求作业进度外,客户端每5秒都会通过调用waitForCompletion()来检查作业是否完成。时间间隔可以通过mapreduce.client.completion.pollinterval来设置。作业完成之后,应用管理器和Container会清理工作状态。作业的信息会被作业历史服务器存储以备之后用户核查

发布了6 篇原创文章 · 获赞 7 · 访问量 149

猜你喜欢

转载自blog.csdn.net/weixin_45678465/article/details/105364527