|
Attached the patch for review.
This patch uses setsid while creating tasks(map/reduce) and uses "kill – -processGroupID" to kill all the processes in the process group, thus killing the whole subtree of processes. Of course, this will not work if the mapper/reducer itself uses setsid or setpgid for any of the processes in the subtree of processes we are trying to handle. I've not looked at this patch. But from the description, and a few discussions, the implementation likely will undergo changes after
Attached the patch which fixes a problem in earlier patch(In earlier patch, pidFile was not getting created if TaskMemoryManager is not enabled).
Please review the patch and provide your comments. Fixed a findbugs warning and attached the new patch.
Submitting the patch for review....
Please provide your comments. Thanks. Had a look at the code. The basic functionality seems fine. Didn't run and check it manually myself, will do so ASAP.
Comments:
TestCases:
That is all I have for now We should document on which platforms we have setsid available. If it isn't availabe everywhere, we should in the minimum try to fall back to the current mechanism of launching tasks without job control.
Few more code comments:
Attaching an intermediate patch
(1) As we are moving pidfiles beyond the scope of memory management, we should move the pidfile related api(getPidFilePath, removePidFile) out of TaskMemoryManager. Moved them to TaskTracker. (2) destroySubprocessTree() should also ensure that the process-tree is indeed terminated/killed by sending SIGKILL if needed. We should do something in the line of ProcfsBasedProcessTree.SigKillThread. destroySubprocessTree() ensures that the process-tree is indeed terminated/killed by sending SIGKILL. SigKillThread is moved from ProcfsBasedProcessTree to a separate file. (3) I think the check to ensure that the process is the process group leader should be made always. This adds one more level of confidence that we are indeed killing the right process. But this should be done in destroySubprocessTree() and only when used by TT. In other cases, this may not be the case. So we need to separate this may be by having separate api for destroySession and destroySubprocessTree. TT would use destroySession. The check to ensure that the process is the process group leader is made always. Now we have destroyProcessGroup() instead of destroySubProcessTree(). Testcase: Increased the memoryLimit to 30MB so that the subtree would be bigger(now it has 8 processes). Added a verification in TestProcfsBasedProcessTree that checks if all the sub-processes are indeed wiped off. Attaching patch
Attaching the patch
Please review the patch and provide your comments. Attaching the patch with a little change — Now destroyProcessGroup and destroyProcess in ProcessTree will take sleeptime-before-sigkill as a parameter.
The overall summary of the patch is as follows: (1) Using setsid when starting a task sothat all the subprocesses of the task will have the same sessionId and processGroupId as that of the java task(and java task is the process group leader). (2) Using pidFile(earlier created only for TaskMemoryManagerThread; Now created even if memory manager is disabled) for getting the pid of the java task. (3) Killing the whole process group if setsid was used to create the java task. Killing only the java task(similar to earlier) if setsid is not supported on the machine. (4) Moved getPidFilePath(), removePidFile() from TaskMemoryManagerThread to TaskTracker as they are independent of TaskMemoryManagerThread. (5) Created a new class ProcessTree with destroy() - for destroying the process tree(killing the process group if setsid is supported, killing only the java task otherwise). Also moved isAlive(pid), getPidFromPidFile() to ProcessTree as they are independent of ProcfsBasedProcessTree. destroyProcessGroup verifies if the given pid is indeed a process group leader. (6) destroyProcessGroup() and destroyProcess() in ProcessTree class ensures that the process-tree is indeed terminated/killed by sending SIGKILL if SIGTERM is ignored. SigKillThread is moved to ProcessTree as a static inner class and made it to kill (a) single process or (b) process group based on a param. sigkill also takes a parameter whether sigkill is to be sent in the same thread OR in a separate thread(in the background). (7) In TestProcfsBasedProcessTree, (a) using setsid to create java task, (b) using build.test.data as the testdir instead of creating shellScript and pidFile in current dir, (c) added a check that verifies if the whole the process-tree is indeed killed or not(This is done by constructing the whole subtree of processes and traversing it and checking if any of the processes is alive). (8) Added a new testcase(with MiniMRCluster) that tests killJob of job that has tasks with children(or subtree of processes) and verifies if the subprocesses are also killed. KillMapperWIthChild is the mapper that just sleeps till it gets killed. +1 for the patch. Can a committer have a look at this and give a code review? Devaraj?
Few miscelleneous points:
Offline, Ravi commented that it can be done in this patch itself. Only one minor change is needed for pipes, so. Attaching the patch that handles pipes applications sothat the c++ process will not get its own session id — but instead gets the same session id as the java task(the parent of c++ process).
Ran gridmix to check performance impact. Average perf got is 2860sec, which is fine.
Attaching a patch which fixes a javadoc warning.
test-patch gives: [exec] +1 overall. Unit tests also passed on my local machine. Thanks Vinod for pinting out the backwards incompatibility of prototype change for public method captureOutAndError and few in ProcfsBasedProcessTree.
Attaching the patch that fixes the incompatibility issue. test-patch gives:
[exec] +1 overall. Unit tests also passed on my local machine. Looks good overall. Some comments:
1) The ProcessTree class could have destroy methods that take a boolean to decide whether to destroy the process group or a single process. 2) We can avoid calling the ProcfsBasedProcessTree.destroyProcess calls in JvmManager and only call the ProcessTree.destroy. The only thing that is additionally checked for in the ProcfsBasedProcessTree.destroyProcess is whether the pid passed is the process group leader. In our usecase, we are sure that this pid IS the process group leader... Longer term, we should consider refactoring the ProcessTree class so that it is a generic class with specific implementations like ProcfsBasedProcessTree and others deriving from it and overriding methods, much like the hierarchy we have for the FileSystem classes.. Attaching patch with the above 2 comments from Devaraj.
Unit tests passed on my local machine. ant test-patch gave:
[exec] +1 overall. Unit tests also passed on my local machine. I just committed this. Thanks Ravi and Vinod!
Integrated in Hadoop-trunk #756 (See http://hudson.zones.apache.org/hudson/job/Hadoop-trunk/756/
Editorial pass over all release notes prior to publication of 0.21.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
More discussion here: http://issues.apache.org/jira/browse/HADOOP-2092?focusedCommentId=12537386#action_12537386