源码分析-Reduce阶段shuffle分析

更新:以hadoop2.7.2版本重新修改

Reducer类在执行的时候,通常包含3个阶段,SHUFFLE,SORT,REDUCE。具体可参考TaskStatus中的内部类Phase定义。
Shuffle阶段,主要是把map阶段写到本地磁盘的输出,通过网络,拉到执行reduce节点的本地。该阶段代码主要在ReduceTask这个类中。

1,Shuffle的启动实机


这个是由ReduceTask决定的。理论上,Reducetask启动后,shuffle进程就会起来。

参数mapreduce.job.reduce.slowstart.completedmaps(位于MRJobConfig类中,mr相关的参数大部分位于该类),该值默认是0.05f。
Reduce在启动之前,会计算已经完成的map数占所有map数的比例,只有大于设置的比例(默认0.05)时,Reduce才会启动。

具体逻辑见下代码:RMContainerAllocator
      int completedMapsForReduceSlowstart = (int)Math.ceil(reduceSlowStart * 
                      totalMaps);
      if(completedMaps < completedMapsForReduceSlowstart) {
        LOG.info("Reduce slow start threshold not met. " +
              "completedMapsForReduceSlowstart " + 
            completedMapsForReduceSlowstart);
        return;
      } else {
        LOG.info("Reduce slow start threshold reached. Scheduling reduces.");
        setIsReduceStarted(true);
      }

2,获取map输出结果



Shuffle的主要实现在ShuffleConsumerPlugin。在Hadoop2中,该类是个接口,便于用户扩展。当然,大部分用户不会主动去扩展,用的是该接口的一个
默认实现类Shuffle。

2.1 怎么取结果

取结果的主要实现是Fetcher类,该类继承自Thread。为了加快shuffle速度,Shuffle内部会构造一个Fetcher数组,多线程去拷贝数据。
数组的大小取决于mapreduce.reduce.shuffle.parallelcopies,默认为5。每个Fecher内部其实是通过http去pull map结果所在节点的数据。

2.2 存结果

2.1步骤取到的结果会存在内存或者磁盘中。主要的存取逻辑在代码MergeManagerImpl中。

问题:哪些map数据放到内存?哪些放到磁盘?
放map结果之前,会调用canShuffleToMemory方法,判断拿到的map结果是否可以放入内存
 private boolean canShuffleToMemory(long requestedSize) {
    return (requestedSize < maxSingleShuffleLimit); 
  }

requestedSize 是pull的map结果大小,
maxSingleShuffleLimit,计算逻辑如下:
this.maxSingleShuffleLimit = (long)(memoryLimit * singleShuffleMemoryLimitPercent);

memoryLimit计算逻辑如下
this.memoryLimit = (long)(jobConf.getLong(MRJobConfig.REDUCE_MEMORY_TOTAL_BYTES,Runtime.getRuntime().maxMemory()) * maxInMemCopyUse);
maxInMemCopyUse取决于参数mapreduce.reduce.shuffle.input.buffer.percent,默认0.70f;
MRJobConfig.REDUCE_MEMORY_TOTAL_BYTES取决于参数mapreduce.reduce.memory.totalbytes,默认值其实是reduce进程当前最大可用内存。


另外singleShuffleMemoryLimitPercent取决于参数mapreduce.reduce.shuffle.memory.limit.percent,默认为0.25f
故map默认的最大结果= reduce当前可用最大内存*0.75*0.25 :
1)当pull的map结果大小>该值,数据放入磁盘。
2)当pul的map结果大小<该值,当前已用的内存是否超过了内存限制,没超过,放内存
2)当pul的map结果大小<该值,当前已用的内存是否超过了内存限制,超过了,等待.

关于上面的参数,如果想看reducetask计算时的实时值,可以通过log,如下:
2017-04-20 11:49:03,213 INFO [main] org.apache.hadoop.mapreduce.task.reduce.MergeManagerImpl: MergerManager: memoryLimit=802632512, maxSingleShuffleLimit=200658128, mergeThreshold=529737472, ioSortFactor=10, memToMemMergeOutputsThreshold=10


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值