MR–Map源码
要是看提交任务和map是怎么连通的 需要从提交任务这边找到最后提交任务那里
由此进入
走到这一步,点击submitJob进入
这个job 继承了thread new的时候 下面调用了一个start 开启线程 所以job里面的run方法 被调用 ,进入本地实现类中。
线程启动在这里,我们去寻找一下run
我们直接找对应的run方法,线程的真正开启,是线程的run方法
- TaskSplitMetaInfo[] taskSplitMetaInfos =
SplitMetaInfoReader.readSplitMetaInfo(jobId, localFs, conf, systemJobDir);
// 读取job.splitmetainfo
- int numReduceTasks = job.getNumReduceTasks(); // 获取ReduceTask个数
3. List mapRunnables = getMapTaskRunnables(
taskSplitMetaInfos, jobId, mapOutputFiles);
// 根据切片的个数, 创建执行MapTask的 MapTaskRunnable
4. ExecutorService mapService = createMapExecutor(); // 创建线程池
5. runTasks(mapRunnables, mapService, “map”); //执行 MapTaskRunnable
6. 因为Runnable提交给线程池执行,接下来会执行MapTaskRunnable的run方法。
7. 执行 LocalJobRunner
MapTaskRunnable 的run()方法
7.1MapTask map = new MapTask(systemJobFile.toString(),mapId,taskId,info.getSplitIndex(), 1); //创建MapTask对象
7.2 map.run(localConf, Job.this); //执行MapTask中的run方法
点击run进入run方法,会发现另一片天地----MapTask类中。
7.2.1 .runNewMapper(job, splitMetaInfo, umbilical, reporter);
split = getSplitDetails(new Path(splitIndex.getSplitLocation()),splitIndex.getStartOffset()); // 重构切片对象
切片对象的信息 : file:/D:/input/inputWord/JaneEyre.txt:0+36306679
output = new NewOutputCollector(taskContext, job, umbilical, reporter); //构造缓冲区对象
collector = createSortingCollector(job, reporter); //获取缓冲区对象
MapTask$MapOutputBuffer
collector.init(context); //初始化缓冲区对象
.final float spillper =
job.getFloat(JobContext.MAP_SORT_SPILL_PERCENT, (float)0.8); // 溢写百分比 0.8
final int sortmb = job.getInt(MRJobConfig.IO_SORT_MB,MRJobConfig.DEFAULT_IO_SORT_MB); // 缓冲区大小 100M
sorter = ReflectionUtils.newInstance(job.getClass( MRJobConfig.MAP_SORT_CLASS,QuickSort.class,IndexedSorter.class), job);
// 排序对象
// 排序使用的是快排,并且基于索引排序。
开始kv序列化
然后走output counters// 计数器
走compression // 压缩
走// combiner // combiner
总结:
mapper.run(mapperContext); // 执行WordCountMapper中的run方法。 实际执行的是
WordCountMapper继承的Mapper中的run方法。
[1] . 在Mapper中的run方法中
map(context.getCurrentKey(), context.getCurrentValue(), context);
执行到WordCountMapper中的map方法。
[2] . 在WordCountMapper中的map方法中将kv写出
context.write(outK,outV);