/** * update progress rate for a task * * <p>The assumption is that the JIP lock is held entering this routine. So it's left * unsynchronized. Currently the only places it's called from are TIP.updateStatus and * JIP.refreshCandidate* */ public void updateProgressRate(long currentTime) { double bestProgressRate = 0; for (TaskStatus ts : taskStatuses.values()) { if (ts.getRunState() == TaskStatus.State.RUNNING || ts.getRunState() == TaskStatus.State.SUCCEEDED || ts.getRunState() == TaskStatus.State.COMMIT_PENDING) { double tsProgressRate = ts.getProgress() / Math.max(1, currentTime - getDispatchTime(ts.getTaskID())); if (tsProgressRate > bestProgressRate) { bestProgressRate = tsProgressRate; } } } DataStatistics taskStats = job.getRunningTaskStatistics(isMapTask()); taskStats.updateStatistics(progressRate, bestProgressRate); progressRate = bestProgressRate; }
/** * Can this task be speculated? This requires that it isn't done or almost done and that it isn't * already being speculatively executed. * * <p>Added for use by queue scheduling algorithms. * * @param currentTime */ boolean canBeSpeculated(long currentTime) { if (skipping || !isRunnable() || !isRunning() || completes != 0 || isOnlyCommitPending() || activeTasks.size() > MAX_TASK_EXECS) { return false; } if (isSpeculativeForced()) { return true; } // no speculation for first few seconds if (currentTime - lastDispatchTime < speculativeLag) { return false; } DataStatistics taskStats = job.getRunningTaskStatistics(isMapTask()); if (LOG.isDebugEnabled()) { LOG.debug( "activeTasks.size(): " + activeTasks.size() + " " + activeTasks.firstKey() + " task's progressrate: " + progressRate + " taskStats : " + taskStats); } // if the task is making progress fast enough to complete within // the acceptable duration allowed for each task - do not speculate if ((maxProgressRateForSpeculation > 0) && (progressRate > maxProgressRateForSpeculation)) { return false; } if (isMapTask() ? job.shouldSpeculateAllRemainingMaps() : job.shouldSpeculateAllRemainingReduces()) { if (LOG.isDebugEnabled()) { LOG.debug("Speculate " + getTIPId() + " because the job is almost finished"); } return true; } // Find if task should be speculated based on standard deviation // the max difference allowed between the tasks's progress rate // and the mean progress rate of sibling tasks. double maxDiff = (taskStats.std() == 0 ? taskStats.mean() / 3 : job.getSlowTaskThreshold() * taskStats.std()); // if stddev > mean - we are stuck. cap the max difference at a // more meaningful number. maxDiff = Math.min(maxDiff, taskStats.mean() * job.getStddevMeanRatioMax()); return (taskStats.mean() - progressRate > maxDiff); }