资源的申请,分配过程略过,从开始执行开始。缓存
mapper阶段: 首先调用默认的PathFilter进行文件过滤,肯定哪些输入文件是须要的哪些是不须要的,而后调用inputFormat的getSplits方法进行文件的分割,返回inputSplit列表,每一个inputSplit会分到对应的mapper执行。以后调用默认的createRecordReader()方法,肯定传给map函数处理的key和value。map函数执行的结果先存到缓存中,默认大小是100M,当达到阀值0.8也就是80M时会写入磁盘文件,写入磁盘以前会进行分区,不一样区的数据会给不用的reduce处理。调用默认Partitioner的getPartition()方法进行分区,分区以后进行key默认的排序,也可让自定义的key实现WriteableComparable接口进行自定义排序规则。排序后进行分组,分组的目的时key值相同的,value会放到一个集合中,可让key值继承RowComparator实现自定义分组。分组后看用户是否自定义了Combine(能够说是本地reduce程序),若是定义了则执行Combine函数进行合并数据,合并后写入本地磁盘。当map任务结束以前会进行一次所有文件的合并,由于在map的执行过程达到80M会进行写一次文件,可能存在多个文件,因此须要进行一次合并。过程是同样的,会进行分区,排序,分组,若是有Combine则进行Combine,不一样分区的结果存放在一个文件中,经过索引进行区分不一样的分区。固然对于map的结果能够进行可选性压缩,须要进行手动的设置。app
reduce阶段: 从各个map节点获取本身对应的分区,map的完成时间时不一样的,reduce会周期性的询问是否有完成的map须要copy,reduce存在5个copy线程(能够经过mapreduce.reduce.shuffle.parallelcopies配置),一旦有属于本身的那部分分区的map执行完,就会将其copy过来。map端不会当即删除数据,由于可能出现reduce失败重作。
若是map输出的数据足够小,则会被拷贝到reduce任务的JVM内存中(能够经过mapreduce.reduce.shuffle.input.buffer.percent配置JVM堆内存的多少比例能够用于存放map任务的输出结果)。若是数据太大容不下,则被拷贝到reduce的机器磁盘上。当达到缓冲区的阀值时,会写入磁盘,后台的一个线程会对写入磁盘的文件进行合并和排序,若是有Combine同时也进行Combine较少占用存储大小。最后会造成一个排序后的文件,做为reduce的输入。执行结果保存到hdfs。函数