1YarnChild 调用MapTask#run方法
2在执行MapTask的时候,会产生一个Mapper实例,然后调用其run方法,run方法又会调用map方法。
3map方法会初始化一些操作,然后从Context判断是否存在下一个key-value文本键值对,其本质是根据RecordReader#nextKeyValue读取的,如果存在则取出这个key和value传入到map方法
4根据传入的key和 value,key就是当前的value的偏移量offset,value就是当前的一行数据。然后再在map方法处理具体的逻辑,并把新的key和value写入context,将计算结果写入内存缓冲区
5这时候开始进入shuffle阶段:分区,排序,分组,溢写,合并,复制等
6Map Task运行完毕之后,就要运行ReduceTask了。由YarnChild调用到ReduceTask#run方法,主要做copy,sort和reduce操作。
7copy阶段:
7.1装配SuffleConsumerPlugin插件,并做一些初始化操作,然后调用该插件的run方法
7.2在run方法内部构造EventFetcher线程类, 获取已经完成的Map的事件,并遍历获取的事件,通过SuffleScheduler#resolve方法把这些已经完成Map 任务的主机名添加到一个Map集合,
7.3构造一个Fetcher线程类数组,判断是不是从本地获取,如果是本地获取,设置数组数量为1;否则根据mapreduce.reduce.shuffle.
Parallelcopies参数设置,如果没有默认是5.
7.4遍历Fetcher线程类,启动线程,然后调用copyFromHost方法,
获取ShuffleScheduler已经得到的当前已经完成的map任务的主机的map集合,然后根据是从内存还是磁盘上复制,开始到那台主机copymap任务的结果
7.5复制完毕,停止线程,停止ShuffleScheduler
8 设置当前任务状态为Sort阶段,开始进行Reduce的merge操作,并返回一个Key-Value的迭代器RawKeyValueIterator对象,如何进行排序操作的呢?是根据比较器,在构造的时候RawKeyValueIterator会传递一个比较器
9Sort阶段完毕,设置当前任务阶段为Reduce阶段,并调用runNewReduce方法,调用Reducer#run方法
10判断是否还有一个key,如果有则取出key和value,然后调用reduce方法,然后进行reduce操作
11最后输出结果