目录

hadoop工作流程描述

  1. 客户端提交一个任务到Resource Manager中的Application Manager
    1. Resource Manager失败,基于zookeeper的HA,一旦master挂掉,shandby立刻变成master详见
  2. Application Manager启动一个App master
  3. App master向Application Manager注册自己
  4. App master开始分切分map(按文件和block size)
    1. 如果App master失败,Application Manager负责再次启动App master详见
  5. App master向Resource Manager中的 Resource Scheduler申请资源
  6. Resource Scheduler为每个map task返回一个nodemanager
  7. App master 通知nodemanager 为map task启动一个container
    1. nodemanager或container失败后,由App master 根据机制判断任务是否需要重做详见
  8. nodemanager 启动container运行map task
    1. map task 的输出超过阀值的话会被flush到磁盘(我们称之为“溢出文件”)
      1. io.sort.mb 缓冲区的大小,默认为100M
      2. io.sort.spill.percent map达到缓冲区多少比例后开始flush,默认80%
        1. 这里设置了一个比例,为了保证在写磁盘时,map任务仍有部分内存可用。
    2. 在flush之前会先对结果分区,排序,combiner,尽量保证flush的量越小越好
    3. 当map最后一个记录完成时,可能已经有很多溢出文件了,这时需要将所有溢出文件排序,combiner。后合并成了一个已分区且已排序的数据文件(该文件还伴有一个索引文件,索引文件记录了数据文件中所有partition的起始位置、偏移量)
      1. 分区过程是按照hash算法进行分区的,分区个数reduce个数相等
      2. combiner的目的是尽量减少每次写入磁盘的数据量,和下一复制阶段网络传输的数据量
    4. 为了减少网络传输的数据量,这里可以将数据压缩,只要将mapred.compress.map.out设置为true就可以了
  9. nodemanager 启动container运行reduce task
  10. reduce从各个map结果中下载数据(只取自己需要的分区)
    1. mapred.reduce.parallel.copies 参数控制reduce可以并行从几个map结果中下载相应分区
    2. 如果reduce端接受的数据量相当小,则直接存储在内存中
      1. 缓冲区大小由mapred.job.shuffle.input.buffer.percent属性控制,表示用作此用途的堆空间的百分比
    3. 如果数据量超过了该缓冲区大小的一定比例,则对数据合并后溢写到磁盘中
      1. 由mapred.job.shuffle.merge.percent决定
    4. 随着溢写文件的增多,后台线程会将它们合并成一个更大的有序的文件
      1. 这样做是为了给后面的合并节省时间。其实不管在map端还是reduce端,MapReduce都是反复地执行排序,合并操作
      2. 直到最后一次合并操作,最后一次合并后并不会写到磁盘,而是直接交给reduce函数。现在终于明白了有些人为什么会说:排序是hadoop的灵魂。
  11. reduce操作完成之后写回hdfs
  12. app Master向Application Manager注销自己

组件架构

MapReduce流程