全网最详细的Mapreduce运行原理

Mapredcue原理详解

一、切片机制

可以看我之前写的Mapreduce源码分析(一):FileInputFormat切片机制,源码详解这篇文章,这里只讲流程,不分析代码了

主要是FileInputFormat类中的getSplits(JobContext job)方法来进行切片

  1. 你的数据存放的目录:/input/wc.txt
  2. 遍历你目录下的所有文件
  3. 遍历到第一个文件wc.txt
  4. 计算文件大小long length = file.getLen();
  5. 判断文件是否是本地文件,如果是则给文件分块,如果是hdfs文件,那么直接获取保存文件的数据块信息,把各个数据块的信息存储到BlockLocation[]数组中
  6. 获取数据块大小long blockSize = file.getBlockSize();默认是128M
  7. 计算切片大小:computeSplitSize(blockSize, minSize, maxSize); 如果minSize和maxSize没有重新设置,那么切片大小就是数据块大小=128M
  8. 开始切片,形成第一个切片:wc.txt–0:128M 第二个切片:wc.txt–1:128-256 第三个切片:wc.txt–2:256-300
  9. 将切片信息写到切片规划文件中

二、MapTask读取切片信息

有几个切片就有几个MapTask,每个MapTask分别读取各个切片的数据
10. 实际上MapTask通过LineRecordReader这个类取读取数据的,可以看我之前写的Mapreduce源码分析(二):MapTask及LineRecordReader读取文件的工作机制,源码详解来帮助理解<K,V>键值对从何而来
返回的<Key,Value>,Key代表偏移量,Value代表一行的数据,如下图
在这里插入图片描述
11. 传入Mapper重写的map方法中,经过逻辑处理 形成新的<Key,Value>键值对,以WordCount单词计数来分析,新生成的<k,v>键值对,key保存的是一个单词,value为1表示出现了一次,通过context.write方法输出到OutputCollector中
12. OutputCollector把收集的<k,v>键值对写入到环形缓冲区中

三、环形缓冲区

环形缓冲区:是内存中构造的一个环形数据结构,其实就是一个环形数组,一般为100M
13. 到存储到数据达到环形缓冲区的80%时,会发生溢出
14. 在溢出数据之前会对数据进行分区和排序
分区:根据partition来进行分区,那么partition怎么来的呢?
在HashPartitioner这个类中有个getPartition的方法,其中numReduceTasks就是分区数,可以在Driver那设置,有几个numReduceTasks就有几个reduce输出文件
partition = (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;

 public int getPartition(K key, V value,
                          int numReduceTasks) {
    return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
  }

排序:然后把环形缓冲区中的数据根据partition值进行快速排序(升序),partition值相同的<k,v>为同一个区,
相同的partition会根据key的ASCII码值排序(升序)
【注】如果实体类实现了WritableComparable接口,重写了compareTo方法,key就要用key.compareTo方法对对象进行排序

四、对各个小文件进行归并排序

  1. 将环形缓冲区中排序后的内存数据不断溢出到本地磁盘中,如果map阶段处理的数据较大,可能会溢出多个文件
  2. 多个一处文件会merge合并成一个大的溢出文件,合并采用给归并排序,所以MapTask最终结果还是分区且区内有序的

五、 ReduceTask

  1. ReduceTask根据自己的分区号,区各个MapTask节点上拷贝相同partition的数据到ReduceTask本地磁盘工作目录
  2. ReduceTask会把同一分区的来自不同 MapTask的结果文件 ,在进行merge合并一个大文件(归并排序),大文件内按照key排序
  3. 合并成一个大文件后,根据key分组,调用GroupingComparator,把key相同的放一组,value进行迭代,从文件中每次取出一组<k,v>数据,key是分组的key,value是所有相同key的value的迭代
    如:(“hadoop”,(1,1,1,1,1)),然后调用Reducer中重写的redcue方法进行逻辑处理
  4. 最后通过OutputFormat方法将结果数据写reduce各自的分区文件中

六、总结

  1. 除了环形缓冲区里了数据是放在内存中的,后面的数据包括溢出的和归并的都放在磁盘中
  2. shuffle过程:一个reduce拷贝每个map节点相同partition的数据到ReduceTask本地磁盘工作目录
  3. map输出是什么类型,reduce就要用什么类型接收
  4. 当map中处理的数据较多时,环形缓冲区会溢出很多个文件,可以调用combiner组件,逻辑和reduce一样,,合并相同的key,value迭代这样传效率高,不用传好多的key。

大致流程图如下:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值