【MapReduce详解及源码解析(一)】——分片输入、Mapper及Map端Shuffle过程

本文详细介绍了MapReduce的工作流程,重点解析了输入数据的分片、Mapper处理以及Map端的Shuffle过程。讨论了分片大小的计算,源码分析了FileInputFormat类及其子类,以及各种InputFormat如何将数据转化为键值对。此外,还探讨了Map过程中的关键步骤,包括map函数逻辑、数据输出以及Shuffle阶段的分区、排序、分组和组合操作。
摘要由CSDN通过智能技术生成

title: 【MapReduce详解及源码解析(一)】——分片输入、Mapper及Map端Shuffle过程
date: 2018-12-03 21:12:42
tags: Hadoop
categories: 大数据
toc: true
点击查看我的博客:Josonlee’s Blog
版权声明:本文为博主原创文章,未经博主允许不得转载(https://blog.csdn.net/lzw2016/)



之前在看这一部分内容时,也挺烦的,细读一遍《Hadoop 海量数据处理·范东来著》书和老师给的若干Demo代码,自己再看看MapReduce的部分源码后,感触挺深的。把自己所领会的记录在这里吧,文章挺长,一次可能写不完(写不完下次再说吧)

前瞻

用户向Hadoop提交的最小单位是MR作业job,MR计算的最小单位是任务task。job分为多个task,task又分map任务,reduce任务
在Hadoop1.0版本,客户端向Hadoop提交作业,JobTracker会将该作业拆分为多个任务,并根据心跳信息交由空闲的TaskTracker 启动。一个TaskTracker能够启动的任务数量是由TaskTracker 配置的任务槽(slot) 决定。槽是Hadoop的计算资源的表示模型,Hadoop将各个节点上的多维度资源(CPU、内存等)抽象成一维度的槽,这样就将多维度资源分配问题转换成维度的槽 分配的问题。在实际情况中, Map任务和Reduce任务需要的计算资源不尽相同,Hadoop又将槽分成Map槽和Reduce槽,并且Map任务只能使用Map槽,Reduce任务只能使用Reduce槽。
这样做性能会很低,所以在Hadoop2.0版本,资源管理调度框架改为了Yarn,但MR任然作为计算框架存在

MapReduce过程概览

在这里插入图片描述
这张图出处不知,我也就随便用了

一、输入数据分片并转化为键值对

在进行map计算之前,mapreduce会根据输入文件计算输入分片(input split), 每个输入分片(InputSplit)针对一个map任务输入分片(input split)存储的并非数据本身, 而是逻辑上一个分片长度和一个记录数据的位置的数组。 默认分片等同于块大小,分片大小对MR性能影响很大,尽量和block大小相近可以提供map任务计算的数据本地性

可以设置一个map任务的参考个数值,见参数mapred.map.tasks,只是参考具体还是取决于分片数

下面源码中会看到分片大小具体是如何设定的

MapReduce Input Split(输入分/切片)详解,这篇文章对分片这一块总结的挺不错
​​
看下源码中InputSplit的实现,见InputFormat数据格式转换接口
在这里插入图片描述

如图,左侧是实现该接口的几个格式化数据的类,右侧是该接口的两个抽象方法:getSplits是将数据切分成若干个分片,createRecordReader是将输入的分片解析成键值对(key-value),键是偏移量,值是该行的内容

FileInputFormat类及其子类的相关源码解析

继续看下去,看下用的比较多的FileInputFormat类的源码

  • 分片大小计算
// 计算分片大小
protected long computeSplitSize(long blockSize, long minSize,
                                  long maxSize) {
   
    return Math.max(minSize, Math.min(maxSize, blockSize));
  }

代码中的minSize、maxSize定义

minSize=max{minSplitSize,mapred.min.split.size}
maxSize=mapred.max.split.size

blockSize是块大小,所以就是用设置中这三个参数而定的

  • 数据分片
// 数据分片
 public List<InputSplit> getSplits(JobContext job) throws IOException {
   
    Stopwatch sw = new Stopwatch().start();
    long minSize = Math.max(getFormatMinSplitSize(), getMinSplitSize(job));
    long maxSize = getMaxSplitSize(job);
    // 此处省略

    if (isSplitable(job, path)) {
     
  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值