http://jiwenke.iteye.com/blog/334146
花了许多功夫把Hadoop的mapreduce实现过了一遍,基本线索理清楚了:
1. 任务的运行时TaskTracker通过heartbeat取得
2. TaskTracker得到hearbeatresponse之后,会根据封装在response里的action来决定行为
3. 如果是launchaction的话,调用TasklLauncher,在startNewTasks中的localizeJob调用launchTaskForJob然后再TaskInProgress中launchTask让runner.start(); - 这里面的startNewTasks是在线程中的run方法中,而TaskLauncher的notifyall会把线程唤醒:
- public void addToTaskQueue(LaunchTaskAction action) {
- synchronized (tasksToLaunch) {
- TaskInProgress tip = registerTask(action, this);
- tasksToLaunch.add(tip);
- tasksToLaunch.notifyAll();
- }
- }
而这个addToTaskQueue方法是在offerService中调用的,这样就整过过程就街上了:
- if (action instanceof LaunchTaskAction) {
- addToTaskQueue((LaunchTaskAction)action);
- } else if (action instanceof CommitTaskAction)
4. 这个时候就回到TaskRunner.run中去launchJVM,当然要把这个JVM的参数构造好,这个JVM就是我们看到map任务运行的JVM
5. 然后JVMRunner会spawn JVM, 这是通过shexe Child这个类来实现的,这个Child的main就是新起的JVM的主函数入口
6.在Child.main中会对任务的类型进行判断,调用相应的MapTask.run和ReduceTask.run
7.这个时候就可以看到mapper.map入口啦,然后就开始执行用户定义的mapper!
所以Child启动以后的log输出和前面TaskTracker的输出不在同一个文件里,因为已经不是一个虚拟机了。