/** * Check the ACLs for a user doing the passed operation. * * <ul> * <li>If ACLs are disabled, allow all users. * <li>Otherwise, if the operation is not a job operation(for eg. submit-job-to-queue), then * allow only (a) clusterOwner(who started the cluster), (b) cluster administrators and (c) * members of queue-submit-job-acl for the queue. * <li>If the operation is a job operation, then allow only (a) jobOwner, (b) clusterOwner(who * started the cluster), (c) cluster administrators, (d) members of queue admins acl for the * queue and (e) members of job acl for the job operation * </ul> * * @param job the job on which operation is requested * @param callerUGI the user who is requesting the operation * @param operation the operation for which authorization is needed * @throws AccessControlException */ void checkAccess(JobInProgress job, UserGroupInformation callerUGI, Operation operation) throws AccessControlException { String queue = job.getProfile().getQueueName(); String jobId = job.getJobID().toString(); JobStatus jobStatus = job.getStatus(); String jobOwner = jobStatus.getUsername(); AccessControlList jobAcl = jobStatus.getJobACLs().get(operation.jobACLNeeded); checkAccess(jobId, callerUGI, queue, operation, jobOwner, jobAcl); }
@Override protected void updateRunnability() { // Start by marking everything as not runnable for (JobInfo info : infos.values()) { info.runnable = false; } // Create a list of sorted jobs in order of start time and priority List<JobInProgress> jobs = new ArrayList<JobInProgress>(infos.keySet()); Collections.sort(jobs, new FifoJobComparator()); // Mark jobs as runnable in order of start time and priority, until // user or pool limits have been reached. Map<String, Integer> userJobs = new HashMap<String, Integer>(); Map<String, Integer> poolJobs = new HashMap<String, Integer>(); for (JobInProgress job : jobs) { if (isWait(job)) { LOG.debug("Booked job. It's waiting... : " + job.getJobID()); continue; } String user = job.getJobConf().getUser(); String pool = poolMgr.getPoolName(job); int userCount = userJobs.containsKey(user) ? userJobs.get(user) : 0; int poolCount = poolJobs.containsKey(pool) ? poolJobs.get(pool) : 0; if (userCount < poolMgr.getUserMaxJobs(user) && poolCount < poolMgr.getPoolMaxJobs(pool)) { if (job.getStatus().getRunState() == JobStatus.RUNNING || job.getStatus().getRunState() == JobStatus.PREP) { userJobs.put(user, userCount + 1); poolJobs.put(pool, poolCount + 1); JobInfo jobInfo = infos.get(job); if (job.getStatus().getRunState() == JobStatus.RUNNING) { jobInfo.runnable = true; } else { // The job is in the PREP state. Give it to the job initializer // for initialization if we have not already done it. if (jobInfo.needsInitializing) { jobInfo.needsInitializing = false; jobInitializer.initJob(jobInfo, job); } } } } } }
// create a new TaskInProgress and make it running by adding it to jobtracker private TaskInProgress createAndAddTIP(JobTracker jobtracker, JobInProgress jip, TaskType type) { JobConf conf = jip.getJobConf(); JobID id = jip.getJobID(); // now create a fake tip for this fake job TaskInProgress tip = null; if (type == TaskType.MAP) { tip = new TaskInProgress(id, "dummy", JobSplit.EMPTY_TASK_SPLIT, jobtracker, conf, jip, 0, 1); jip.maps = new TaskInProgress[] {tip}; } else if (type == TaskType.REDUCE) { tip = new TaskInProgress(id, "dummy", jip.desiredMaps(), 0, jobtracker, conf, jip, 1); jip.reduces = new TaskInProgress[] {tip}; } else if (type == TaskType.JOB_SETUP) { tip = new TaskInProgress(id, "dummy", JobSplit.EMPTY_TASK_SPLIT, jobtracker, conf, jip, 0, 1); jip.setup = new TaskInProgress[] {tip}; } else if (type == TaskType.JOB_CLEANUP) { tip = new TaskInProgress(id, "dummy", JobSplit.EMPTY_TASK_SPLIT, jobtracker, conf, jip, 0, 1); jip.cleanup = new TaskInProgress[] {tip}; } return tip; }
@Override public Task assignTask(TaskTrackerStatus tts, long currentTime, Collection<JobInProgress> visited) throws IOException { if (isRunnable()) { visited.add(job); TaskTrackerManager ttm = scheduler.taskTrackerManager; ClusterStatus clusterStatus = ttm.getClusterStatus(); int numTaskTrackers = clusterStatus.getTaskTrackers(); if (taskType == TaskType.MAP) { LocalityLevel localityLevel = scheduler.getAllowedLocalityLevel(job, currentTime); scheduler.getEventLog().log("ALLOWED_LOC_LEVEL", job.getJobID(), localityLevel); // obtainNewMapTask needs to be passed 1 + the desired locality level return job.obtainNewMapTask( tts, numTaskTrackers, ttm.getNumberOfUniqueHosts(), localityLevel.toCacheLevelCap()); } else { return job.obtainNewReduceTask(tts, numTaskTrackers, ttm.getNumberOfUniqueHosts()); } } else { return null; } }
@Override public synchronized List<Task> assignTasks(TaskTracker taskTracker) throws IOException { TaskTrackerStatus taskTrackerStatus = taskTracker.getStatus(); ClusterStatus clusterStatus = taskTrackerManager.getClusterStatus(); final int numTaskTrackers = clusterStatus.getTaskTrackers(); final int clusterMapCapacity = clusterStatus.getMaxMapTasks(); final int clusterReduceCapacity = clusterStatus.getMaxReduceTasks(); Collection<JobInProgress> jobQueue = jobQueueJobInProgressListener.getJobQueue(); // // Get map + reduce counts for the current tracker. // final int trackerMapCapacity = taskTrackerStatus.getMaxMapSlots(); final int trackerReduceCapacity = taskTrackerStatus.getMaxReduceSlots(); final int trackerRunningMaps = taskTrackerStatus.countMapTasks(); final int trackerRunningReduces = taskTrackerStatus.countReduceTasks(); // Assigned tasks List<Task> assignedTasks = new ArrayList<Task>(); // // Compute (running + pending) map and reduce task numbers across pool // int remainingReduceLoad = 0; int remainingMapLoad = 0; synchronized (jobQueue) { for (JobInProgress job : jobQueue) { if (job.getStatus().getRunState() == JobStatus.RUNNING) { remainingMapLoad += (job.desiredMaps() - job.finishedMaps()); if (job.scheduleReduces()) { remainingReduceLoad += (job.desiredReduces() - job.finishedReduces()); } } } } // Compute the 'load factor' for maps and reduces double mapLoadFactor = 0.0; if (clusterMapCapacity > 0) { mapLoadFactor = (double) remainingMapLoad / clusterMapCapacity; } double reduceLoadFactor = 0.0; if (clusterReduceCapacity > 0) { reduceLoadFactor = (double) remainingReduceLoad / clusterReduceCapacity; } // // In the below steps, we allocate first map tasks (if appropriate), // and then reduce tasks if appropriate. We go through all jobs // in order of job arrival; jobs only get serviced if their // predecessors are serviced, too. // // // We assign tasks to the current taskTracker if the given machine // has a workload that's less than the maximum load of that kind of // task. // However, if the cluster is close to getting loaded i.e. we don't // have enough _padding_ for speculative executions etc., we only // schedule the "highest priority" task i.e. the task from the job // with the highest priority. // final int trackerCurrentMapCapacity = Math.min((int) Math.ceil(mapLoadFactor * trackerMapCapacity), trackerMapCapacity); int availableMapSlots = trackerCurrentMapCapacity - trackerRunningMaps; boolean exceededMapPadding = false; if (availableMapSlots > 0) { exceededMapPadding = exceededPadding(true, clusterStatus, trackerMapCapacity); } int numLocalMaps = 0; int numNonLocalMaps = 0; boolean newIterationJob = false; scheduleMaps: for (int i = 0; i < availableMapSlots; ++i) { synchronized (jobQueue) { for (JobInProgress job : jobQueue) { if (job.getStatus().getRunState() != JobStatus.RUNNING) { continue; } if (job.getJobConf().isIterative()) { String iterativeAppID = job.getJobConf().getIterativeAlgorithmID(); if (iterativeAppID.equals("none")) { throw new IOException("please specify the iteration ID!"); } String jointype = job.getJobConf().get("mapred.iterative.jointype"); // prepare the iterationid map and jobtask map if (!this.tracker_mtask_map.containsKey(iterativeAppID)) { // a new iterative algorithm Map<String, LinkedList<Integer>> new_tracker_task_map = new HashMap<String, LinkedList<Integer>>(); this.tracker_mtask_map.put(iterativeAppID, new_tracker_task_map); Map<String, LinkedList<Integer>> new_tracker_rtask_map = new HashMap<String, LinkedList<Integer>>(); this.tracker_rtask_map.put(iterativeAppID, new_tracker_rtask_map); // record the first job of the series of jobs in the iterations this.first_job_map.put(iterativeAppID, job.getJobID()); // record the list of jobs for a iteration HashSet<JobID> jobs = new HashSet<JobID>(); jobs.add(job.getJobID()); this.iteration_jobs_map.put(iterativeAppID, jobs); } // this is the first job of the series of jobs if (this.first_job_map.get(iterativeAppID).equals(job.getJobID()) && job.getJobConf().isIterative()) { LOG.info(job.getJobID() + " is the first iteration job"); newIterationJob = true; } // this is one of the following jobs, and prepare a assignment list for the assignment if (!newIterationJob) { LOG.info(job.getJobID() + " is not the first iteration job"); this.iteration_jobs_map.get(iterativeAppID).add(job.getJobID()); if (this.mtask_assign_map.get(job.getJobID()) == null) { // prepare the map task assignment list LOG.info("for job " + job.getJobID() + "'s assignment:"); Map<String, LinkedList<Integer>> map_task_assign = new HashMap<String, LinkedList<Integer>>(); for (Map.Entry<String, LinkedList<Integer>> entry : this.tracker_mtask_map.get(iterativeAppID).entrySet()) { String tracker = entry.getKey(); LinkedList<Integer> taskids = entry.getValue(); LinkedList<Integer> copytaskids = new LinkedList<Integer>(); LOG.info("assign on tracker " + tracker); for (int taskid : taskids) { copytaskids.add(taskid); LOG.info("task id " + taskid); } map_task_assign.put(tracker, copytaskids); } this.mtask_assign_map.put(job.getJobID(), map_task_assign); // if one2one copy the map assign to reduce assign, the are with the same mapping if (jointype.equals("one2one")) { // prepare the reduce task assignment list Map<String, LinkedList<Integer>> reduce_task_assign = new HashMap<String, LinkedList<Integer>>(); for (Map.Entry<String, LinkedList<Integer>> entry : this.tracker_mtask_map.get(iterativeAppID).entrySet()) { String tracker = entry.getKey(); LinkedList<Integer> taskids = entry.getValue(); LinkedList<Integer> copytaskids = new LinkedList<Integer>(); for (int taskid : taskids) { copytaskids.add(taskid); } reduce_task_assign.put(tracker, copytaskids); } this.tracker_rtask_map.put(iterativeAppID, reduce_task_assign); } // prepare the reduce task assignment list for all cases Map<String, LinkedList<Integer>> reduce_task_assign = new HashMap<String, LinkedList<Integer>>(); for (Map.Entry<String, LinkedList<Integer>> entry : this.tracker_rtask_map.get(iterativeAppID).entrySet()) { String tracker = entry.getKey(); LinkedList<Integer> taskids = entry.getValue(); LinkedList<Integer> copytaskids = new LinkedList<Integer>(); for (int taskid : taskids) { copytaskids.add(taskid); } reduce_task_assign.put(tracker, copytaskids); } this.rtask_assign_map.put(job.getJobID(), reduce_task_assign); } } Task t = null; // the first iteration or following iteration // if the first iteration: assign taskid by default (exception for the one2mul case, // where we assign staring from 0,...,n) // else if the following iterations: assign taskid based on the first iteration // assignment if (newIterationJob) { /** * the one2mul case should be carefully taken care, we want to assgin map0,map1,map2 * and reduce0 to a tracker, and assign map3,map4,map5 and reduce1 to another tracker */ if (jointype.equals("one2mul") && !tracker_rtask_map .get(iterativeAppID) .containsKey(taskTracker.getTrackerName())) { // if contain the tracker, that means we have assigned tasks for this tracker int scala = job.getJobConf().getInt("mapred.iterative.data.scala", 1); // int mapsEachTracker = job.getJobConf().getNumMapTasks() / numTaskTrackers; int reducersEachTracker = job.getJobConf().getNumReduceTasks() / numTaskTrackers; if (job.getJobConf().getNumReduceTasks() % numTaskTrackers != 0) throw new IOException( "job.getJobConf().getNumReduceTasks() % numTaskTrackers != 0"); if (!this.tracker_mtask_map .get(iterativeAppID) .containsKey(taskTracker.getTrackerName())) { LinkedList<Integer> tasklist = new LinkedList<Integer>(); this.tracker_mtask_map .get(iterativeAppID) .put(taskTracker.getTrackerName(), tasklist); } if (!this.tracker_rtask_map .get(iterativeAppID) .containsKey(taskTracker.getTrackerName())) { LinkedList<Integer> tasklist = new LinkedList<Integer>(); this.tracker_rtask_map .get(iterativeAppID) .put(taskTracker.getTrackerName(), tasklist); } // for debugging String debugout1 = "maps: "; String debugout2 = "reduces: "; int reduceOffsetId = (tracker_rtask_map.get(iterativeAppID).size() - 1) * reducersEachTracker; // the start reduce id for (int count = 0; count < reducersEachTracker; count++) { int reducepartitionid = reduceOffsetId + count; debugout2 += reducepartitionid + " "; tracker_rtask_map .get(iterativeAppID) .get(taskTracker.getTrackerName()) .add(reducepartitionid); for (int count2 = 0; count2 < scala; count2++) { int mappartitionid = reducepartitionid * scala + count2; // int mapid = job.splitTaskMap.get(mappartitionid); debugout1 += mappartitionid + " "; this.tracker_mtask_map .get(iterativeAppID) .get(taskTracker.getTrackerName()) .add(mappartitionid); } } // print out for debug LOG.info( "tracker " + taskTracker.getTrackerName() + " assigned tasks " + debugout1 + " and " + debugout2); // make the assignment list String tracker = taskTracker.getTrackerName(); LinkedList<Integer> mtaskids = this.tracker_mtask_map.get(iterativeAppID).get(taskTracker.getTrackerName()); LinkedList<Integer> mcopytaskids = new LinkedList<Integer>(); for (int taskid : mtaskids) { mcopytaskids.add(taskid); } if (!mtask_assign_map.containsKey(job.getJobID())) { Map<String, LinkedList<Integer>> map_task_assign = new HashMap<String, LinkedList<Integer>>(); this.mtask_assign_map.put(job.getJobID(), map_task_assign); } this.mtask_assign_map.get(job.getJobID()).put(tracker, mcopytaskids); // prepare the reduce task assignment list LinkedList<Integer> rtaskids = this.tracker_rtask_map.get(iterativeAppID).get(taskTracker.getTrackerName()); LinkedList<Integer> rcopytaskids = new LinkedList<Integer>(); for (int taskid : rtaskids) { rcopytaskids.add(taskid); } if (!rtask_assign_map.containsKey(job.getJobID())) { Map<String, LinkedList<Integer>> reduce_task_assign = new HashMap<String, LinkedList<Integer>>(); this.rtask_assign_map.put(job.getJobID(), reduce_task_assign); } this.rtask_assign_map.get(job.getJobID()).put(tracker, rcopytaskids); // assign a map task for this tracker Integer target = null; try { target = this.mtask_assign_map .get(job.getJobID()) .get(taskTracker.getTrackerName()) .peekFirst(); } catch (Exception e) { e.printStackTrace(); } if (target == null) { // all have been assigned, no more work, maybe it should help others to process LOG.info( "all map tasks on tasktracker " + taskTracker.getTrackerName() + " have been processed"); break; } else { t = job.obtainNewNodeOrRackLocalMapTask( taskTrackerStatus, numTaskTrackers, taskTrackerManager.getNumberOfUniqueHosts(), target); } } else { t = job.obtainNewNodeOrRackLocalMapTask( taskTrackerStatus, numTaskTrackers, taskTrackerManager.getNumberOfUniqueHosts()); } } else { Integer target = null; try { target = this.mtask_assign_map .get(job.getJobID()) .get(taskTracker.getTrackerName()) .peekFirst(); } catch (Exception e) { e.printStackTrace(); } if (target == null) { // all have been assigned, no more work, maybe it should help others to process LOG.info( "all map tasks on tasktracker " + taskTracker.getTrackerName() + " have been processed"); break; } else { t = job.obtainNewNodeOrRackLocalMapTask( taskTrackerStatus, numTaskTrackers, taskTrackerManager.getNumberOfUniqueHosts(), target); } } if (t != null) { assignedTasks.add(t); ++numLocalMaps; // new iteration job and the first task for a tasktracker // for one2mul case, we don't need to record the assignment, since we already made the // assignment list beforehand if (!newIterationJob || jointype.equals("one2mul")) { // poll, remove this.mtask_assign_map .get(job.getJobID()) .get(taskTracker.getTrackerName()) .pollFirst(); LOG.info("assigning task " + t.getTaskID() + " on " + taskTracker.getTrackerName()); } else { // record the assignment list for map tasks if (!this.tracker_mtask_map .get(iterativeAppID) .containsKey(taskTracker.getTrackerName())) { LinkedList<Integer> tasklist = new LinkedList<Integer>(); this.tracker_mtask_map .get(iterativeAppID) .put(taskTracker.getTrackerName(), tasklist); } this.tracker_mtask_map .get(iterativeAppID) .get(taskTracker.getTrackerName()) .add(t.getTaskID().getTaskID().getId()); // prepare the reduce assignment, for mapping with reduce if (jointype.equals("one2one")) { // prepare the reduce assignment, for mapping with reduce if (!first_job_reduces_map.containsKey(iterativeAppID)) { Map<String, LinkedList<Integer>> tracker_reduce_map = new HashMap<String, LinkedList<Integer>>(); first_job_reduces_map.put(iterativeAppID, tracker_reduce_map); } if (!first_job_reduces_map .get(iterativeAppID) .containsKey(taskTracker.getTrackerName())) { LinkedList<Integer> reduces = new LinkedList<Integer>(); first_job_reduces_map .get(iterativeAppID) .put(taskTracker.getTrackerName(), reduces); } first_job_reduces_map .get(iterativeAppID) .get(taskTracker.getTrackerName()) .add(t.getTaskID().getTaskID().getId()); } LOG.info("assigning task " + t.getTaskID() + " on " + taskTracker.getTrackerName()); } // Don't assign map tasks to the hilt! // Leave some free slots in the cluster for future task-failures, // speculative tasks etc. beyond the highest priority job if (exceededMapPadding) { break scheduleMaps; } // Try all jobs again for the next Map task break; } LOG.error("New Node Or Rack Local Map Task failed!"); if (newIterationJob) { // Try to schedule a node-local or rack-local Map task t = job.obtainNewNonLocalMapTask( taskTrackerStatus, numTaskTrackers, taskTrackerManager.getNumberOfUniqueHosts()); } else { Integer target = this.mtask_assign_map .get(job.getJobID()) .get(taskTracker.getTrackerName()) .peekFirst(); if (target == null) { // all have been assigned, no more work, maybe it should help others to process LOG.info( "all map tasks on tasktracker " + taskTracker.getTrackerName() + " have been processed"); break; } else { t = job.obtainNewNonLocalMapTask( taskTrackerStatus, numTaskTrackers, taskTrackerManager.getNumberOfUniqueHosts(), target); } } if (t != null) { assignedTasks.add(t); ++numNonLocalMaps; // new iteration job and the first task for a tasktracker if (newIterationJob) { if (!this.tracker_mtask_map .get(iterativeAppID) .containsKey(taskTracker.getTrackerName())) { LinkedList<Integer> tasklist = new LinkedList<Integer>(); this.tracker_mtask_map .get(iterativeAppID) .put(taskTracker.getTrackerName(), tasklist); } this.tracker_mtask_map .get(iterativeAppID) .get(taskTracker.getTrackerName()) .add(t.getTaskID().getTaskID().getId()); } else { // poll, remove this.mtask_assign_map .get(job.getJobID()) .get(taskTracker.getTrackerName()) .pollFirst(); } // We assign at most 1 off-switch or speculative task // This is to prevent TaskTrackers from stealing local-tasks // from other TaskTrackers. break scheduleMaps; } } else { // not an iterative algorithm, normal schedule Task t = null; // Try to schedule a node-local or rack-local Map task t = job.obtainNewNodeOrRackLocalMapTask( taskTrackerStatus, numTaskTrackers, taskTrackerManager.getNumberOfUniqueHosts()); if (t != null) { assignedTasks.add(t); ++numLocalMaps; // Don't assign map tasks to the hilt! // Leave some free slots in the cluster for future task-failures, // speculative tasks etc. beyond the highest priority job if (exceededMapPadding) { break scheduleMaps; } // Try all jobs again for the next Map task break; } // Try to schedule a node-local or rack-local Map task t = job.obtainNewNonLocalMapTask( taskTrackerStatus, numTaskTrackers, taskTrackerManager.getNumberOfUniqueHosts()); if (t != null) { assignedTasks.add(t); ++numNonLocalMaps; // We assign at most 1 off-switch or speculative task // This is to prevent TaskTrackers from stealing local-tasks // from other TaskTrackers. break scheduleMaps; } } } } } int assignedMaps = assignedTasks.size(); // // Same thing, but for reduce tasks // However we _never_ assign more than 1 reduce task per heartbeat // /** should maintain the reduce task location for the termination check */ final int trackerCurrentReduceCapacity = Math.min((int) Math.ceil(reduceLoadFactor * trackerReduceCapacity), trackerReduceCapacity); final int availableReduceSlots = Math.min((trackerCurrentReduceCapacity - trackerRunningReduces), 1); boolean exceededReducePadding = false; // LOG.info("availableReduceSlots " + availableReduceSlots); if (availableReduceSlots > 0) { exceededReducePadding = exceededPadding(false, clusterStatus, trackerReduceCapacity); synchronized (jobQueue) { for (JobInProgress job : jobQueue) { LOG.info("job " + job.getJobID()); if (job.getStatus().getRunState() != JobStatus.RUNNING || job.numReduceTasks == 0) { LOG.info("have to continue " + job.getStatus().getRunState()); continue; } Task t = null; if (job.getJobConf().isIterative()) { String iterativeAppID = job.getJobConf().getIterativeAlgorithmID(); if (iterativeAppID.equals("none")) { throw new IOException("please specify the iteration ID!"); } String jointype = job.getJobConf().get("mapred.iterative.jointype"); if (jointype.equals("one2one")) { // one-to-one or one-to-mul jobs if (this.first_job_map.get(iterativeAppID).equals(job.getJobID()) && job.getJobConf().isIterative()) { LOG.info(job.getJobID() + " is the first iteration job for reduce"); newIterationJob = true; } Integer target = null; if (newIterationJob) { if (first_job_reduces_map.get(iterativeAppID) == null) { throw new IOException( "I think something is wrong since the tasktracker never receive " + "a map task with iterativeapp id " + iterativeAppID); } if (first_job_reduces_map.get(iterativeAppID).get(taskTracker.getTrackerName()) == null) { throw new IOException( "I think something is wrong since the tasktracker never receive " + "a map task with iterativeapp id " + iterativeAppID + " from " + taskTracker.getTrackerName()); } target = this.first_job_reduces_map .get(iterativeAppID) .get(taskTracker.getTrackerName()) .pollFirst(); } else { // the task assignment has already been processed during the map task assignment, so // never use tracker_rtask_map target = this.rtask_assign_map .get(job.getJobID()) .get(taskTracker.getTrackerName()) .pollFirst(); } if (target == null) { // all have been assigned, no more work, maybe it should help others to process LOG.info( "all reduce tasks on tasktracker " + taskTracker.getTrackerName() + " have been processed"); break; } else { t = job.obtainNewReduceTask( taskTrackerStatus, numTaskTrackers, taskTrackerManager.getNumberOfUniqueHosts(), target); } } else if (jointype.equals("one2mul")) { Integer target = this.rtask_assign_map .get(job.getJobID()) .get(taskTracker.getTrackerName()) .pollFirst(); if (target == null) { // all have been assigned, no more work, maybe it should help others to process LOG.info( "all reduce tasks on tasktracker " + taskTracker.getTrackerName() + " have been processed"); break; } else { t = job.obtainNewReduceTask( taskTrackerStatus, numTaskTrackers, taskTrackerManager.getNumberOfUniqueHosts(), target); } } else { // one-to-all case, assign tasks in the first iteration job, and remember this mapping // this is the first job of the series of jobs if (this.first_job_map.get(iterativeAppID).equals(job.getJobID())) { LOG.info(job.getJobID() + " is the first iteration job for reduce"); newIterationJob = true; } /* //this is one of the following jobs, and prepare a assignment list for the assignment else{ LOG.info(job.getJobID() + " is not the first iteration job for reduce"); if(this.rtask_assign_map.get(job.getJobID()) == null){ //prepare the map task assignment list Map<String, LinkedList<Integer>> reduce_task_assign = new HashMap<String, LinkedList<Integer>>(); for(Map.Entry<String, LinkedList<Integer>> entry : this.tracker_rtask_map.get(iterativeAppID).entrySet()){ String tracker = entry.getKey(); LinkedList<Integer> taskids = entry.getValue(); LinkedList<Integer> copytaskids = new LinkedList<Integer>(); for(int taskid : taskids){ copytaskids.add(taskid); } reduce_task_assign.put(tracker, copytaskids); } this.rtask_assign_map.put(job.getJobID(), reduce_task_assign); } } */ // the first iteration or following iteration // if the first iteration: assign taskid by default // else if the following iterations: assign taskid based on the first iteration // assignment if (newIterationJob) { t = job.obtainNewReduceTask( taskTrackerStatus, numTaskTrackers, taskTrackerManager.getNumberOfUniqueHosts()); if (t != null) { if (!this.tracker_rtask_map .get(iterativeAppID) .containsKey(taskTracker.getTrackerName())) { LinkedList<Integer> tasklist = new LinkedList<Integer>(); this.tracker_rtask_map .get(iterativeAppID) .put(taskTracker.getTrackerName(), tasklist); } this.tracker_rtask_map .get(iterativeAppID) .get(taskTracker.getTrackerName()) .add(t.getTaskID().getTaskID().getId()); LOG.info( "assigning reduce task " + t.getTaskID() + " on " + taskTracker.getTrackerName()); } } else { Integer target = this.rtask_assign_map .get(job.getJobID()) .get(taskTracker.getTrackerName()) .peekFirst(); if (target == null) { // all have been assigned, no more work, maybe it should help others to process LOG.info( "all map tasks on tasktracker " + taskTracker.getTrackerName() + " have been processed"); break; } else { t = job.obtainNewReduceTask( taskTrackerStatus, numTaskTrackers, taskTrackerManager.getNumberOfUniqueHosts(), target); } if (t != null) { // poll, remove this.rtask_assign_map .get(job.getJobID()) .get(taskTracker.getTrackerName()) .pollFirst(); LOG.info( "assigning reduce task " + t.getTaskID() + " on " + taskTracker.getTrackerName()); } } } } else { t = job.obtainNewReduceTask( taskTrackerStatus, numTaskTrackers, taskTrackerManager.getNumberOfUniqueHosts()); } LOG.info("try to assign new task " + t); if (t != null) { assignedTasks.add(t); break; } // Don't assign reduce tasks to the hilt! // Leave some free slots in the cluster for future task-failures, // speculative tasks etc. beyond the highest priority job if (exceededReducePadding) { break; } } } } if (LOG.isDebugEnabled()) { LOG.debug( "Task assignments for " + taskTrackerStatus.getTrackerName() + " --> " + "[" + mapLoadFactor + ", " + trackerMapCapacity + ", " + trackerCurrentMapCapacity + ", " + trackerRunningMaps + "] -> [" + (trackerCurrentMapCapacity - trackerRunningMaps) + ", " + assignedMaps + " (" + numLocalMaps + ", " + numNonLocalMaps + ")] [" + reduceLoadFactor + ", " + trackerReduceCapacity + ", " + trackerCurrentReduceCapacity + "," + trackerRunningReduces + "] -> [" + (trackerCurrentReduceCapacity - trackerRunningReduces) + ", " + (assignedTasks.size() - assignedMaps) + "]"); } return assignedTasks; }
@Override public String getName() { return job.getJobID().toString(); }