MR工作原理

一、MR Job是怎么运行起来的

整体流程如下所示,整体来看,有如下五个组件:

  1. 客户端,负责提交任务
  2. YARN Resource Manager,负责协调集群的资源分配
  3. YARN Node Manager,负责启动和监视集群中的container
  4. MapReduce application master,负责协调MR Job中的task;MRAppMaster和MR task都在container中运行,container受ResourceManager的调度,受NodeManager的管理
  5. 分布式文件系统(如HDFS),用于与其他组件共享Job文件
    在这里插入图片描述

1.1 Job提交

  1. 向ResourceManager申请一个application id,用于当作MR Job的id(step2)
  2. 检查Job指定的输出路径,如果没有指定路径或者该路径已存在,则报错;
  3. 计算输入的split,如果split计算失败(如因为没有指定input路径等原因),则报错;
  4. 把Job所需的文件复制到分布式文件系统上(step3),包括Job Jar包、配置文件、计算好的input split切片等
  5. 通过调用submitApplication()方法向RM提交Job

1.2 Job初始化

  1. 当RM接收到submitApplication()的调用请求后,它将该请求下发给Yarn scheduler,scheduler分配一个container,然后RM在该container上启动MRAPPMaster,改container在NM的管理下(step 5a, 5b)

  2. 初始化Job,这一步创建许多 bookkeeping object 来接收task的完成进度

  3. 从分布式文件系统上拿到在客户端计算好的split信息,然后为每一个split创建一个maptask,并为每个task分配task id(step 7)

    AppMaster负责决定怎样运行task,如果Job足够小,就会让task与AppMaster在同一个JVM运行,当AppMaster判断在新的container上分配和运行任务的开销大于在一个节点上运行任务的开销,就会发生这种情况。

    Job足够小的默认判断标准:mapper的个数小于10,且只有1个reducer,且input size小于hdfs的block size

    最后,在所有的task可以运行以前,AppMaster通过调用OutputCommitter的setupJob()方法,来为Job创建最终的输出目录和task输出的临时目录

1.3 Task分配

  1. 如果任务不满足和AppMaster运行在同一个JVM的条件,那AppMaster就会向ResourceManager申请container来运行maptask和reducetask(step8),maptask优先于reducetask运行,因为reduce的sort阶段必须在maptask全部完成以后才可以运行

    reducetask可以在集群的任意节点上运行,但是maptask会受到数据局部性限制,即优先运行于split所在的节点;或者运行在与split相同的机架上;

1.4 Task执行

  1. 一旦task被resource manager的scheduler分配container后,AppMaster就和NodeManager沟通启动container(9a, 9b)
  2. task被主类是YarnChild的Java程序启动,在它运行task之前,先初始化task所需的资源,包括task所需的配置文件和Jar包,以及分布式缓存上的文件(step10);
  3. 启动task(step11)

YarnChild在一个单独的JVM上运行,所以它不会被用户定义的map/reduce task所影响而导致失败,

二、Shuffle And Sort

mapreduce保证输入数据到每个reduce都是排好序的,系统执行排序(包括map端排序和reduce端排序)、传输map输出到reducer的输入,称之为shuffle,

在这里插入图片描述

注意:在mr过程中,combine可能会发生多次

2.1 map side

每一个map task都有一个环形缓冲区,默认大小是100MB,可以通过 mapreduce.task.io.sort.mb property来调节,当缓冲区的利用率达到80%就会启动溢写,在溢写过程中,缓冲区中还会同时被写入数据,当写满后就会阻塞;

在把数据写到磁盘以前,首先会对数据进行分区,然后对分区内的数据进行排序,排序算法和数据量有关,如果元素个数小于13,则用冒泡排序,否则用快排。如果指定了combiner,那它会在排序的结果上进行combine。combine可以减少溢写磁盘和reduce传输的数据量(1)。

每当缓冲区达到溢写的阈值,就会产生一个溢写文件,所以当map task输出最后一条记录后,可能会有几个溢写文件,在map task结束之前,会将文件合并到单个分区且有序的文件中;

如果至少有3个溢写文件(可以通过mapreduce.map.combine.minspills指定),那combiner将会被再次运行。如果溢写文件个数小于3,那map减少的输出可能不值得调用合并器,所以在这种情况下不会触发combine。(3)

我们也可以在map输出到磁盘的时候进行压缩,这样可以加快溢写过程、减少磁盘使用和减少数据传输

2.2 reduce side

reduce有3个阶段:copy、sort和reduce

copy: map阶段的完成速度都不一样,所以reducer会在每一个maptask结束以后就开始copy,如果复制的数据量足够小,就会把数据复制到内存中。当内存缓冲区中复制的数据量达到阈值(mapreduce.reduce.shuffle.merge.percent)或者复制的个数达到阈值(mapreduce.reduce.merge.inmem.threshold),会进行合并和溢写磁盘。如果指定了combiner,将会先进行combine再溢写。(3)

sort: 在复制结束以后,进入sort阶段(更合理的叫法,应该是merge,因为sort在map端已经进行了),在merge时,是分回合进行的。例如,如果我们有50个文件,合并因子是10 (mapreduce.task.io.sort.factor),那将合并5个回合,每个回合将10个文件合并成1个文件,最终产出5个中间文件。

合并过程,其实也并不是完全按照上述事例所描述的这样,它会更加自适应,例如我们有40个文件,合并因子是10,那么merge过程就不会产出四个大小相同的中间文件,而是产出一个小的和三个大的中间文件,最后剩下的文件和中间文件在reduce端进行合并,这样可以减少中间结果的产生量。(这种算法并不会减少合并的轮次,但是可以减少中间文件溢写磁盘的大小

具体过程如下:第一轮合并4个,第二、三、四轮各合并10个,这时候就有4个中间文件,最后再和剩下的6个文件在reduce阶段合并。

在这里插入图片描述

同理,50个文件的合并过程我们可以分成5、10、10、10、10、5合并

**reduce:**在reduce阶段,排好序的每个key将会执行reduce中定义好的方法,reduce的输出将会直接写到文件系统,如HDFS。

三、任务执行

一、Speculative Execution(推测执行)

在MR中,Job被分成很多task并行执行,task的个数常常会很多,几千几万个很正常,这么多task中,经常会存在个别task运行的很慢,任务可能由于各种原因变慢,如硬件降级或者软件配置错误,但是原因很难检测到,因为任务还可以运行成功,尽管运行时间比预期的要长。Hadoop不会去诊断并修复这些慢的任务,相反,它会检测那些比预期时间要长的任务,然后新起一个相同的任务作为备份,这称之为Speculative Execution of task。

必须要注意的是,Speculative Execution 并不会将所有的task都做备份, 这样会十分浪费资源,相反的,它会监测所有任务的运行进度,然后一小部分将运行时间大于平均时间的任务进行备份。在 Speculative Execution 中,当一个任务执行成功后,另一个任务就会被杀死,即如果原始任务执行成功,那备份任务将被杀死;或者备份任务执行成功,原始任务就会被杀死。

Speculative Execution默认是开启的,但在如下情况下需要关闭:

  1. 因为Speculative Execution会为一个Job启动多个相同的task,在繁忙的集群中,这样会降低集群的吞吐量;
  2. 当网络是性能瓶颈时,关闭reduce task的Speculative Execution,避免多个reduce传输同一份数据,减小集群中的网络压力;

有时候,集群管理员会将整个集群的Speculative Execution设置成false,而让用户在个人的任务中开启,Speculative Execution参数如下:

parameter_namedefault_value
mapreduce.map.speculativetrue
mapreduce.reduce.speculativetrue
yarn.app.mapreduce.am.job.speculator.class
yarn.app.mapreduce.am.job.task.estimator.class
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值