03_MapReduce框架原理_3.6 Shuffle机制(源码)

点击查看 Shuffle 流程图


点击查看 Shuffle 机制 说明 Hadoop
6. Shuffle 机制 - (流程) 1. 什么是Shuffle&Shuffle的作用 1. Map方法之后,Reduce方法之前的数据处理过程 称之为 Shuffle 2. 流程说明 1. MapTask 通过获取到的 切片对象和相对于的记录读取器 map()方法 处理数据 后的输出结果(key-value) 会输出到 内存缓冲区 2. 当 内存缓冲区 快满的时候,需要将缓冲区的数据 用一个 临时文件的方式 存储到磁盘 这个过程 叫做 溢写过程 临时文件 叫做 溢写文件 3. 当MapTask结束后再对磁盘中 所有的 溢写文件做合并,生成最终的输出文件 等待reduce task来拉取数据 这个过程 叫做 merge 4. 在溢出过程及合并过程中,都要调用Partitioner进行分区和针对key排序 5. ReduceTask 根据自己分配到的分区号,去各自MapTask机器上拉取相应的结果分区数据 6. ReduceTask 会拉取同一个分区的数据(来自不同MapTask的结果文件) ReduceTask 会将这些文件在进行合并(归并排序) 7. ReduceTask 合并成大文件后,Shuffle 过程也就结束了 8. ReduceTask 逻辑运算过程,遍历相同的key,并对value做reduce操作 3. 注意事项 1. Shuffle 缓冲区的大小会影响 MapReduce程序的执行效率 缓冲区越大,磁盘io的次数越少,执行速度就越快 2. 缓冲区的大小 可以通过参数调整 参数 : mapreduce.task.io.sort.mb 默认 100M 2. map task的输出结果有效地传送到reduce端
点击查看 Shuffle 源码
Shuffle 机制过程
// 发生时间 : map方法之后,reduce方法之前 (为了解决 MapTask输出如何高效输出到ReduceTask)

/***********************MapTask****************************************************************************************/
//1. map方法处理一行数据,经处理结果 输出到 内存缓冲区(key,value)
  context.write(key, value)

//2. 写入到 环形缓冲区
    // 1. MapTask 类 write 方法
    @Override
    public void write(K key, V value) throws IOException, InterruptedException {
      collector.collect(key, value,
                        // 根据key,value计算当前key 所属的分区编号
                        partitioner.getPartition(key, value, partitions));
    }
    
    //思考:  往 环形缓冲区中写入了内容呢
    //   1. 元数据信息 partition、keystart(标记key在内存中的开始位置)、valstart(标记value在内存中的开始位置)、VALLEN(结束位置)
    //   2. 数据信息 key, value, partition
    // 功能 : 将 key,value 序列化到 内存缓冲区中    
    public synchronized void collect(K key, V value, final int partition) throws IOException {
    // bufferRemaining 为缓冲区大小 默认为 100m
    //      通过  mapreduce.task.io.sort.mb  设置缓冲区大小
    // METASIZE 为存储元数据 
    bufferRemaining -= METASIZE;
    if (bufferRemaining <= 0) {

      // write accounting info
      kvmeta.put(kvindex + PARTITION, partition);
      kvmeta.put(kvindex + KEYSTART, keystart);
      kvmeta.put(kvindex + VALSTART, valstart);
      kvmeta.put(kvindex + VALLEN, distanceTo(valstart, valend));
      // advance kvindex
      kvindex = (kvindex - NMETA + kvmeta.capacity()) % kvmeta.capacity();
    } catch (MapBufferTooSmallException e) {
      LOG.info("Record too large for in-memory buffer: " + e.getMessage());
      spillSingleRecord(key, value, partition);
      mapOutputRecordCounter.increment(1);
      return;
    }
  }   

//3. 溢写过程
   //1. 当 bufferRemaining(缓冲区容量) 使用大于大于80%后,会将内存中 数据写入到 本地磁盘的临时文件中(溢写文件)
        // 溢写前 会将 数据分区、且分区内排序(快排)
        // group by partition(分区编号) order by key

//4. Merge 溢写文件 (生成一个输出文件 group by partition 且 分区内有序),等待reduceTask 的拉取
   //1. 将步骤3 中生成的多个溢写文件 Merge成一个文件 且数据分区、且分区内排序(归并排序)
   //   group by partition(分区编号) order by key

   //2. Combiner合并 (被动触发,必须指定合并器才能执行) job.setCombinerClass(WordCountCombiner.class)
   //   聚合规则(value) group by key

/***********************ReduceTask****************************************************************************************/
//1. 拉取 MapTask结果数据(按分区拉取),并对数据归并排序
  //  1. 每个reduceTask 只处理一个分区的数据
  //  2. 拉取策略(动态归并)  
  //       示例 10个MapTask ,会将先完成的MapTask的数据拉取合并,再与后完成的MapTask合并
//2. 生成 同一分区且有序的数据,供ReduceTask 处理
posted @   学而不思则罔!  阅读(78)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界
点击右上角即可分享
微信分享提示