1、客户端提交,验证输入输出路径、输入数据分片,打包上传到jobtracker ... ...


2、map过程:

      map输出会写到map端的跟jobID相关的temp目录(mapred.local.dir)下,但输出并非简单输出到磁盘;

     1)首先输出到内存缓冲区(默认为100M,由io.sort.mb参数控制)

     2)缓冲区使用率到阈值时(默认是0.80,由io.sort.spill.percent参数控制),后台线程会将缓冲区写到磁盘;与此同时map会继续向缓冲区写入数据,如果缓冲区被写满,那么map会阻塞知道溢写过程完成。

     3)溢写过程以轮询的方式进行,根据reducer数量将缓冲区数据分区,首先会对分区数据进行内排序,然后运行combiner(如果有),然后写到磁盘。

     4)缓冲区可能多次超过阈值,所以溢写过程会重复多次,每次溢写,对于同一分区的输出会创建一个新的溢写文件。

     5)map任务完成后,会对多个溢写文件进行合并为一个已分区并且已排序的输出文件,多次迭代进行,一次合并处理10个(默认10个,由io.sort.factor参数控制)溢写文件,最终合并为1个。

     6)如果溢写次数大于等于3次(默认为3,由参数min.num.spills.for.combine控制)并且设置了combiner,则在合并输出时将执行combiner (???也就是说如果溢写紧急发生2次,那么合并后并不会进行combine操作,则在有combine函数的job中,reduce函数也可能会收到来自同一map输出的2个同一的key???)


3、reduce过程:

   1)只要有map任务完成,reducer就开始从mapper复制数据,如果有多个mapper已经完成,则会启动多个线程进行复制(默认为5,由参数mapred.reduce.parallel.copies参数控制)

   2)reducer复制数据也会写到内存缓冲区中(缓冲区大小由mapred.job.shuffle.input.buffer.percent参数控制,表示占堆大小的百分比),如果复制的文件太大(怎么判定?)则直接写到磁盘,对复制到缓冲区的情况,如果超过阈值(mapred.job.shuffle.merge.percent参数控制),则溢写到磁盘

   3)从多个map输出复制到reducer的数据形成过个文件,reducer会对数据进行合并和排序,每轮合并10个(由io.sort.factor参数控制)文件,最后一轮合并结果直接输入到reduce函数

   4)reduce函数执行,并将输出写到hdfs


4、map输出数据删除,mapper会等待整个job执行完成后才删除数据,而非所有reducer复制数据完成后,因为reducer可能会挂掉,所以在任务完成后,jobtracker通知mapper删除。