PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/src/mapred/org/apache/hadoop/mapred/TaskController.java

https://github.com/coderplay/hadoop-common
Java | 409 lines | 179 code | 43 blank | 187 comment | 11 complexity | 48eb2b7b13b5b9a94f2b2f82804c2e28 MD5 | raw file
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. package org.apache.hadoop.mapred;
  19. import java.io.File;
  20. import java.io.IOException;
  21. import org.apache.commons.logging.Log;
  22. import org.apache.commons.logging.LogFactory;
  23. import org.apache.hadoop.conf.Configurable;
  24. import org.apache.hadoop.conf.Configuration;
  25. import org.apache.hadoop.fs.FileSystem;
  26. import org.apache.hadoop.fs.Path;
  27. import org.apache.hadoop.mapred.CleanupQueue.PathDeletionContext;
  28. import org.apache.hadoop.mapred.JvmManager.JvmEnv;
  29. import org.apache.hadoop.mapreduce.server.tasktracker.Localizer;
  30. import org.apache.hadoop.util.StringUtils;
  31. import org.apache.hadoop.util.Shell.ShellCommandExecutor;
  32. /**
  33. * Controls initialization, finalization and clean up of tasks, and
  34. * also the launching and killing of task JVMs.
  35. *
  36. * This class defines the API for initializing, finalizing and cleaning
  37. * up of tasks, as also the launching and killing task JVMs.
  38. * Subclasses of this class will implement the logic required for
  39. * performing the actual actions.
  40. * <p>
  41. * 控制任务的初始化、结束及清理,以及启动和杀死任务JVM.
  42. * 见https://issues.apache.org/jira/browse/HADOOP-4490
  43. * <br/>
  44. *
  45. * NOTE: This class is internal only class and not intended for users!!
  46. */
  47. public abstract class TaskController implements Configurable {
  48. private Configuration conf;
  49. public static final Log LOG = LogFactory.getLog(TaskController.class);
  50. public Configuration getConf() {
  51. return conf;
  52. }
  53. // The list of directory paths specified in the variable mapred.local.dir.
  54. // This is used to determine which among the list of directories is picked up
  55. // for storing data for a particular task.
  56. protected String[] mapredLocalDirs;
  57. public void setConf(Configuration conf) {
  58. this.conf = conf;
  59. mapredLocalDirs = conf.getStrings("mapred.local.dir");
  60. }
  61. /**
  62. * Sets up the permissions of the following directories on all the configured
  63. * disks:
  64. * <ul>
  65. * <li>mapred-local directories</li>
  66. * <li>Hadoop log directories</li>
  67. * </ul>
  68. */
  69. public void setup() throws IOException {
  70. for (String localDir : this.mapredLocalDirs) {
  71. // Set up the mapred-local directories.
  72. File mapredlocalDir = new File(localDir);
  73. if (!mapredlocalDir.exists() && !mapredlocalDir.mkdirs()) {
  74. LOG.warn("Unable to create mapred-local directory : "
  75. + mapredlocalDir.getPath());
  76. } else {
  77. Localizer.PermissionsHandler.setPermissions(mapredlocalDir,
  78. Localizer.PermissionsHandler.sevenFiveFive);
  79. }
  80. }
  81. // Set up the user log directory
  82. File taskLog = TaskLog.getUserLogDir();
  83. if (!taskLog.exists() && !taskLog.mkdirs()) {
  84. LOG.warn("Unable to create taskLog directory : " + taskLog.getPath());
  85. } else {
  86. Localizer.PermissionsHandler.setPermissions(taskLog,
  87. Localizer.PermissionsHandler.sevenFiveFive);
  88. }
  89. }
  90. /**
  91. * Take task-controller specific actions to initialize job. This involves
  92. * setting appropriate permissions to job-files so as to secure the files to
  93. * be accessible only by the user's tasks.
  94. *
  95. * @throws IOException
  96. */
  97. abstract void initializeJob(JobInitializationContext context) throws IOException;
  98. /**
  99. * Take task-controller specific actions to initialize the distributed cache
  100. * file. This involves setting appropriate permissions for these files so as
  101. * to secure them to be accessible only their owners.
  102. *
  103. * @param context
  104. * @throws IOException
  105. */
  106. public abstract void initializeDistributedCacheFile(DistributedCacheFileContext context)
  107. throws IOException;
  108. /**
  109. * Launch a task JVM
  110. *
  111. * This method defines how a JVM will be launched to run a task. Each
  112. * task-controller should also do an
  113. * {@link #initializeTask(TaskControllerContext)} inside this method so as to
  114. * initialize the task before launching it. This is for reasons of
  115. * task-controller specific optimizations w.r.t combining initialization and
  116. * launching of tasks.
  117. *
  118. * @param context the context associated to the task
  119. */
  120. abstract void launchTaskJVM(TaskControllerContext context)
  121. throws IOException;
  122. /**
  123. * Top level cleanup a task JVM method.
  124. *
  125. * The current implementation does the following.
  126. * <ol>
  127. * <li>Sends a graceful terminate signal to task JVM allowing its sub-process
  128. * to cleanup.</li>
  129. * <li>Waits for stipulated period</li>
  130. * <li>Sends a forceful kill signal to task JVM, terminating all its
  131. * sub-process forcefully.</li>
  132. * </ol>
  133. *
  134. * @param context the task for which kill signal has to be sent.
  135. */
  136. final void destroyTaskJVM(TaskControllerContext context) {
  137. terminateTask(context);
  138. try {
  139. Thread.sleep(context.sleeptimeBeforeSigkill);
  140. } catch (InterruptedException e) {
  141. LOG.warn("Sleep interrupted : " +
  142. StringUtils.stringifyException(e));
  143. }
  144. killTask(context);
  145. }
  146. /** Perform initializing actions required before a task can run.
  147. *
  148. * For instance, this method can be used to setup appropriate
  149. * access permissions for files and directories that will be
  150. * used by tasks. Tasks use the job cache, log, and distributed cache
  151. * directories and files as part of their functioning. Typically,
  152. * these files are shared between the daemon and the tasks
  153. * themselves. So, a TaskController that is launching tasks
  154. * as different users can implement this method to setup
  155. * appropriate ownership and permissions for these directories
  156. * and files.
  157. */
  158. abstract void initializeTask(TaskControllerContext context)
  159. throws IOException;
  160. /**
  161. * Contains task information required for the task controller.
  162. */
  163. static class TaskControllerContext {
  164. // task being executed
  165. Task task;
  166. ShellCommandExecutor shExec; // the Shell executor executing the JVM for this task.
  167. // Information used only when this context is used for launching new tasks.
  168. JvmEnv env; // the JVM environment for the task.
  169. // Information used only when this context is used for destroying a task jvm.
  170. String pid; // process handle of task JVM.
  171. long sleeptimeBeforeSigkill; // waiting time before sending SIGKILL to task JVM after sending SIGTERM
  172. }
  173. /**
  174. * Contains info related to the path of the file/dir to be deleted. This info
  175. * is needed by task-controller to build the full path of the file/dir
  176. */
  177. static abstract class TaskControllerPathDeletionContext
  178. extends PathDeletionContext {
  179. TaskController taskController;
  180. String user;
  181. /**
  182. * mapredLocalDir is the base dir under which to-be-deleted jobLocalDir,
  183. * taskWorkDir or taskAttemptDir exists. fullPath of jobLocalDir,
  184. * taskAttemptDir or taskWorkDir is built using mapredLocalDir, jobId,
  185. * taskId, etc.
  186. */
  187. Path mapredLocalDir;
  188. public TaskControllerPathDeletionContext(FileSystem fs, Path mapredLocalDir,
  189. TaskController taskController,
  190. String user) {
  191. super(fs, null);
  192. this.taskController = taskController;
  193. this.mapredLocalDir = mapredLocalDir;
  194. this.user = user;
  195. }
  196. @Override
  197. protected String getPathForCleanup() {
  198. if (fullPath == null) {
  199. fullPath = buildPathForDeletion();
  200. }
  201. return fullPath;
  202. }
  203. /**
  204. * Return the component of the path under the {@link #mapredLocalDir} to be
  205. * cleaned up. Its the responsibility of the class that extends
  206. * {@link TaskControllerPathDeletionContext} to provide the correct
  207. * component. For example
  208. * - For task related cleanups, either the task-work-dir or task-local-dir
  209. * might be returned depending on jvm reuse.
  210. * - For job related cleanup, simply the job-local-dir might be returned.
  211. */
  212. abstract protected String getPath();
  213. /**
  214. * Builds the path of taskAttemptDir OR taskWorkDir based on
  215. * mapredLocalDir, jobId, taskId, etc
  216. */
  217. String buildPathForDeletion() {
  218. return mapredLocalDir.toUri().getPath() + Path.SEPARATOR + getPath();
  219. }
  220. }
  221. /** Contains info related to the path of the file/dir to be deleted. This info
  222. * is needed by task-controller to build the full path of the task-work-dir or
  223. * task-local-dir depending on whether the jvm is reused or not.
  224. */
  225. static class TaskControllerTaskPathDeletionContext
  226. extends TaskControllerPathDeletionContext {
  227. final Task task;
  228. final boolean isWorkDir;
  229. public TaskControllerTaskPathDeletionContext(FileSystem fs,
  230. Path mapredLocalDir, Task task, boolean isWorkDir,
  231. TaskController taskController) {
  232. super(fs, mapredLocalDir, taskController, task.getUser());
  233. this.task = task;
  234. this.isWorkDir = isWorkDir;
  235. }
  236. /**
  237. * Returns the taskWorkDir or taskLocalDir based on whether
  238. * {@link TaskControllerTaskPathDeletionContext} is configured to delete
  239. * the workDir.
  240. */
  241. @Override
  242. protected String getPath() {
  243. String subDir = (isWorkDir) ? TaskTracker.getTaskWorkDir(task.getUser(),
  244. task.getJobID().toString(), task.getTaskID().toString(),
  245. task.isTaskCleanupTask())
  246. : TaskTracker.getLocalTaskDir(task.getUser(),
  247. task.getJobID().toString(), task.getTaskID().toString(),
  248. task.isTaskCleanupTask());
  249. return subDir;
  250. }
  251. /**
  252. * Makes the path(and its subdirectories recursively) fully deletable by
  253. * setting proper permissions(770) by task-controller
  254. */
  255. @Override
  256. protected void enablePathForCleanup() throws IOException {
  257. getPathForCleanup();// allow init of fullPath, if not inited already
  258. if (fs.exists(new Path(fullPath))) {
  259. taskController.enableTaskForCleanup(this);
  260. }
  261. }
  262. }
  263. /** Contains info related to the path of the file/dir to be deleted. This info
  264. * is needed by task-controller to build the full path of the job-local-dir.
  265. */
  266. static class TaskControllerJobPathDeletionContext
  267. extends TaskControllerPathDeletionContext {
  268. final JobID jobId;
  269. public TaskControllerJobPathDeletionContext(FileSystem fs,
  270. Path mapredLocalDir, JobID id, String user,
  271. TaskController taskController) {
  272. super(fs, mapredLocalDir, taskController, user);
  273. this.jobId = id;
  274. }
  275. /**
  276. * Returns the jobLocalDir of the job to be cleaned up.
  277. */
  278. @Override
  279. protected String getPath() {
  280. return TaskTracker.getLocalJobDir(user, jobId.toString());
  281. }
  282. /**
  283. * Makes the path(and its sub-directories recursively) fully deletable by
  284. * setting proper permissions(770) by task-controller
  285. */
  286. @Override
  287. protected void enablePathForCleanup() throws IOException {
  288. getPathForCleanup();// allow init of fullPath, if not inited already
  289. if (fs.exists(new Path(fullPath))) {
  290. taskController.enableJobForCleanup(this);
  291. }
  292. }
  293. }
  294. /**
  295. * NOTE: This class is internal only class and not intended for users!!
  296. *
  297. */
  298. public static class InitializationContext {
  299. public File workDir;
  300. public String user;
  301. public InitializationContext() {
  302. }
  303. public InitializationContext(String user, File workDir) {
  304. this.user = user;
  305. this.workDir = workDir;
  306. }
  307. }
  308. /**
  309. * This is used for initializing the private localized files in distributed
  310. * cache. Initialization would involve changing permission, ownership and etc.
  311. */
  312. public static class DistributedCacheFileContext extends InitializationContext {
  313. // base directory under which file has been localized
  314. Path localizedBaseDir;
  315. // the unique string used to construct the localized path
  316. String uniqueString;
  317. public DistributedCacheFileContext(String user, File workDir,
  318. Path localizedBaseDir, String uniqueString) {
  319. super(user, workDir);
  320. this.localizedBaseDir = localizedBaseDir;
  321. this.uniqueString = uniqueString;
  322. }
  323. public Path getLocalizedUniqueDir() {
  324. return new Path(localizedBaseDir, new Path(TaskTracker
  325. .getPrivateDistributedCacheDir(user), uniqueString));
  326. }
  327. }
  328. static class JobInitializationContext extends InitializationContext {
  329. JobID jobid;
  330. }
  331. /**
  332. * Sends a graceful terminate signal to taskJVM and it sub-processes.
  333. *
  334. * @param context task context
  335. */
  336. abstract void terminateTask(TaskControllerContext context);
  337. /**
  338. * Enable the task for cleanup by changing permissions of the path
  339. * @param context path deletion context
  340. * @throws IOException
  341. */
  342. abstract void enableTaskForCleanup(PathDeletionContext context)
  343. throws IOException;
  344. /**
  345. * Sends a KILL signal to forcefully terminate the taskJVM and its
  346. * sub-processes.
  347. *
  348. * @param context task context
  349. */
  350. abstract void killTask(TaskControllerContext context);
  351. /**
  352. * Initialize user on this TaskTracer in a TaskController specific manner.
  353. *
  354. * @param context
  355. * @throws IOException
  356. */
  357. public abstract void initializeUser(InitializationContext context)
  358. throws IOException;
  359. /**
  360. * Enable the job for cleanup by changing permissions of the path
  361. * @param context path deletion context
  362. * @throws IOException
  363. */
  364. abstract void enableJobForCleanup(PathDeletionContext context)
  365. throws IOException;
  366. }