diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/InMemoryPlan.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/InMemoryPlan.java index 12a584a..bac876d 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/InMemoryPlan.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/InMemoryPlan.java @@ -687,4 +687,15 @@ public String toString() { readLock.unlock(); } } + + @Override + public RLESparseResourceAllocation getCumulativeLoadOverTime(long start, long end) + { + readLock.lock(); + try { + return rleSparseVector.getRangeOverlapping(start, end); + } finally { + readLock.unlock(); + } + } } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/PlanView.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/PlanView.java index 699f461..d199f25 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/PlanView.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/PlanView.java @@ -173,5 +173,16 @@ public RLESparseResourceAllocation getReservationCountForUserOverTime( */ public RLESparseResourceAllocation getConsumptionForUserOverTime(String user, long start, long end); + + /** + * + * @param start + * @param end + * @return + */ + public RLESparseResourceAllocation getCumulativeLoadOverTime(long start, + long end); } + + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/AlignedPlannerWithGreedy.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/AlignedPlannerWithGreedy.java index b23cf1e..2774b79 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/AlignedPlannerWithGreedy.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/AlignedPlannerWithGreedy.java @@ -57,14 +57,14 @@ public AlignedPlannerWithGreedy(int smoothnessFactor) { // LowCostAligned planning algorithm ReservationAgent algAligned = - new IterativePlanner(new StageEarliestStartByDemand(), - new StageAllocatorLowCostAligned(smoothnessFactor), false); + new IterativePlanner(new StageExecutionIntervalByDemand(), + new StageAllocatorLowCostAligned(smoothnessFactor, false), false); listAlg.add(algAligned); // Greedy planning algorithm ReservationAgent algGreedy = - new IterativePlanner(new StageEarliestStartByJobArrival(), - new StageAllocatorGreedy(), false); + new IterativePlanner(new StageExecutionIntervalUnconstrained(), + new StageAllocatorGreedyRLE(false), false); listAlg.add(algGreedy); // Set planner: diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/GreedyReservationAgent.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/GreedyReservationAgent.java index 915a834..5cdcb7d 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/GreedyReservationAgent.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/GreedyReservationAgent.java @@ -76,7 +76,7 @@ public GreedyReservationAgent(Configuration yarnConfiguration) { } planner = - new IterativePlanner(new StageEarliestStartByJobArrival(), + new IterativePlanner(new StageExecutionIntervalUnconstrained(), new StageAllocatorGreedyRLE(allocateLeft), allocateLeft); } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/IterativePlanner.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/IterativePlanner.java index 24d237a..e1e80d8 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/IterativePlanner.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/IterativePlanner.java @@ -18,7 +18,6 @@ package org.apache.hadoop.yarn.server.resourcemanager.reservation.planning; -import java.util.HashMap; import java.util.HashSet; import java.util.ListIterator; import java.util.Map; @@ -41,17 +40,18 @@ /** * A planning algorithm consisting of two main phases. The algorithm iterates - * over the job stages in descending order. For each stage, the algorithm: 1. - * Determines an interval [stageArrivalTime, stageDeadline) in which the stage - * is allocated. 2. Computes an allocation for the stage inside the interval. - * + * over the job stages in ascending/descending order, depending on the flag + * allocateLeft. For each stage, the algorithm: 1. Determines an interval + * [stageArrival, stageDeadline) in which the stage is allocated. 2. + * Computes an allocation for the stage inside the interval. + * * For ANY and ALL jobs, phase 1 sets the allocation window of each stage to be * [jobArrival, jobDeadline]. For ORDER and ORDER_NO_GAP jobs, the deadline of * each stage is set as succcessorStartTime - the starting time of its * succeeding stage (or jobDeadline if it is the last stage). - * - * The phases are set using the two functions: 1. setAlgEarliestStartTime 2. - * setAlgComputeStageAllocation + * + * The phases are set using the two functions: 1. setAlgStageExecutionInterval + * 2.setAlgStageAllocator */ public class IterativePlanner extends PlanningAlgorithm { @@ -60,7 +60,7 @@ private RLESparseResourceAllocation planModifications; // Data extracted from plan - private Map planLoads; + private RLESparseResourceAllocation planLoads; private Resource capacity; private long step; @@ -70,24 +70,24 @@ private long jobDeadline; // Phase algorithms - private StageEarliestStart algStageEarliestStart = null; + private StageExecutionInterval algStageExecutionInterval = null; private StageAllocator algStageAllocator = null; private final boolean allocateLeft; // Constructor - public IterativePlanner(StageEarliestStart algEarliestStartTime, + public IterativePlanner(StageExecutionInterval algStageExecutionInterval, StageAllocator algStageAllocator, boolean allocateLeft) { this.allocateLeft = allocateLeft; - setAlgStageEarliestStart(algEarliestStartTime); + setAlgStageExecutionInterval(algStageExecutionInterval); setAlgStageAllocator(algStageAllocator); } @Override public RLESparseResourceAllocation computeJobAllocation(Plan plan, - ReservationId reservationId, ReservationDefinition reservation, - String user) throws PlanningException { + ReservationId reservationId, ReservationDefinition reservation, String user) + throws PlanningException { // Initialize initialize(plan, reservationId, reservation); @@ -97,16 +97,11 @@ public RLESparseResourceAllocation computeJobAllocation(Plan plan, new RLESparseResourceAllocation(plan.getResourceCalculator()); StageProvider stageProvider = new StageProvider(allocateLeft, reservation); - + // Current stage ReservationRequest currentReservationStage; - - // Stage deadlines - long stageDeadline = stepRoundDown(reservation.getDeadline(), step); - long successorStartingTime = -1; - long predecessorEndTime = stepRoundDown(reservation.getArrival(), step); - long stageArrivalTime = -1; - + + // Iterate the stages in reverse order while (stageProvider.hasNext()) { @@ -116,28 +111,20 @@ public RLESparseResourceAllocation computeJobAllocation(Plan plan, // Validate that the ReservationRequest respects basic constraints validateInputStage(plan, currentReservationStage); - // Compute an adjusted earliestStart for this resource - // (we need this to provision some space for the ORDER contracts) - - if (allocateLeft) { - stageArrivalTime = predecessorEndTime; - } else { - stageArrivalTime = reservation.getArrival(); - if (jobType == ReservationRequestInterpreter.R_ORDER - || jobType == ReservationRequestInterpreter.R_ORDER_NO_GAP) { - stageArrivalTime = - computeEarliestStartingTime(plan, reservation, - stageProvider.getCurrentIndex(), currentReservationStage, - stageDeadline); - } - stageArrivalTime = stepRoundUp(stageArrivalTime, step); - stageArrivalTime = Math.max(stageArrivalTime, reservation.getArrival()); - } - // Compute the allocation of a single stage - Map curAlloc = + + // Set the stageArrival and stageDeadline + ReservationInterval stageInterval = setStageExecutionInterval(plan, reservation, + currentReservationStage, allocateLeft, allocations); + Long stageArrival = stageInterval.getStartTime(); + Long stageDeadline = stageInterval.getEndTime(); + + + // Compute stage allocation + Map curAlloc = computeStageAllocation(plan, currentReservationStage, - stageArrivalTime, stageDeadline, user, reservationId); - + stageArrival, stageDeadline, user, reservationId); + + // If we did not find an allocation, return NULL // (unless it's an ANY job, then we simply continue). if (curAlloc == null) { @@ -152,10 +139,13 @@ public RLESparseResourceAllocation computeJobAllocation(Plan plan, } - // Get the start & end time of the current allocation - Long stageStartTime = findEarliestTime(curAlloc); - Long stageEndTime = findLatestTime(curAlloc); - + // Validate ORDER_NO_GAP + if (jobType == ReservationRequestInterpreter.R_ORDER_NO_GAP) { + if (!validateOrderNoGap(allocations, curAlloc, allocateLeft)) { + throw new PlanningException("The allocation found does not respect ORDER_NO_GAP"); + } + } + // If we did find an allocation for the stage, add it for (Entry entry : curAlloc.entrySet()) { allocations.addInterval(entry.getKey(), entry.getValue()); @@ -165,36 +155,10 @@ public RLESparseResourceAllocation computeJobAllocation(Plan plan, if (jobType == ReservationRequestInterpreter.R_ANY) { break; } - - // If ORDER job, set the stageDeadline of the next stage to be processed - if (jobType == ReservationRequestInterpreter.R_ORDER - || jobType == ReservationRequestInterpreter.R_ORDER_NO_GAP) { - - // CHECK ORDER_NO_GAP - // Verify that there is no gap, in case the job is ORDER_NO_GAP - // note that the test is different left-to-right and right-to-left - if (jobType == ReservationRequestInterpreter.R_ORDER_NO_GAP - && successorStartingTime != -1 - && ((allocateLeft && predecessorEndTime < stageStartTime) || - (!allocateLeft && (stageEndTime < successorStartingTime)) - ) - || (!isNonPreemptiveAllocation(curAlloc))) { - throw new PlanningException( - "The allocation found does not respect ORDER_NO_GAP"); - } - - if (allocateLeft) { - // Store the stageStartTime and set the new stageDeadline - predecessorEndTime = stageEndTime; - } else { - // Store the stageStartTime and set the new stageDeadline - successorStartingTime = stageStartTime; - stageDeadline = stageStartTime; - } - } - } - - // If the allocation is empty, return an error + + } + + // If the allocation is empty, return an error if (allocations.isEmpty()) { throw new PlanningException("The request cannot be satisfied"); } @@ -203,6 +167,46 @@ public RLESparseResourceAllocation computeJobAllocation(Plan plan, } + + boolean validateOrderNoGap(RLESparseResourceAllocation allocations, + Map curAlloc, boolean allocateLeft) { + + //Left to right + if (allocateLeft) { + + Long stageStartTime = findEarliestTime(curAlloc); + Long allocationEndTime = allocations.getLatestNonNullTime(); + + // Check that there is no gap between stages + if ((allocationEndTime != -1) && (allocationEndTime < stageStartTime)) { + return false; + } + + } + //Right to left + else { + + Long stageEndTime = findLatestTime(curAlloc); + Long allocationStartTime = allocations.getEarliestStartTime(); + + // Check that there is no gap between stages + if ((allocationStartTime != -1) && (stageEndTime < allocationStartTime)) { + return false; + } + + } + + // Check that the stage allocation does not violate ORDER_NO_GAP + if (!isNonPreemptiveAllocation(curAlloc)) { + return false; + } + + // The allocation is legal + return true; + + } + + protected void initialize(Plan plan, ReservationId reservationId, ReservationDefinition reservation) throws PlanningException { @@ -218,40 +222,19 @@ protected void initialize(Plan plan, ReservationId reservationId, // Initialize the plan modifications planModifications = new RLESparseResourceAllocation(plan.getResourceCalculator()); - + // Dirty read of plan load - + // planLoads are not used by other StageAllocators... and don't deal // well with huge reservation ranges - if (this.algStageAllocator instanceof StageAllocatorLowCostAligned) { - planLoads = getAllLoadsInInterval(plan, jobArrival, jobDeadline); - ReservationAllocation oldRes = plan.getReservationById(reservationId); - if (oldRes != null) { - planModifications = - RLESparseResourceAllocation.merge(plan.getResourceCalculator(), - plan.getTotalCapacity(), planModifications, - oldRes.getResourcesOverTime(), RLEOperator.subtract, - jobArrival, jobDeadline); - } - } - - } - - private Map getAllLoadsInInterval(Plan plan, long startTime, - long endTime) { - - // Create map - Map loads = new HashMap(); - - // Calculate the load for every time slot between [start,end) - for (long t = startTime; t < endTime; t += step) { - Resource load = plan.getTotalCommittedResources(t); - loads.put(t, load); - } - - // Return map - return loads; - + planLoads = plan.getCumulativeLoadOverTime(jobArrival, jobDeadline); + ReservationAllocation oldRes = plan.getReservationById(reservationId); + if (oldRes != null) { + planLoads = RLESparseResourceAllocation.merge( + plan.getResourceCalculator(), plan.getTotalCapacity(), + planLoads, oldRes.getResourcesOverTime(), + RLEOperator.subtract, jobArrival, jobDeadline); + } } private void validateInputStage(Plan plan, ReservationRequest rr) @@ -279,15 +262,15 @@ private void validateInputStage(Plan plan, ReservationRequest rr) rr.getCapability(), plan.getMaximumAllocation())) { throw new ContractValidationException( - "Individual capability requests should not exceed cluster's " - + "maxAlloc"); + "Individual capability requests should not exceed cluster's " + + "maxAlloc"); } } - + private boolean isNonPreemptiveAllocation( - Map curAlloc) { + Map curAlloc) { // Checks whether a stage allocation is non preemptive or not. // Assumption: the intervals are non-intersecting (as returned by @@ -329,31 +312,30 @@ private boolean isNonPreemptiveAllocation( } + // Call algEarliestStartTime() - protected long computeEarliestStartingTime(Plan plan, - ReservationDefinition reservation, int index, - ReservationRequest currentReservationStage, long stageDeadline) { + protected ReservationInterval setStageExecutionInterval(Plan plan, ReservationDefinition reservation, + ReservationRequest currentReservationStage, boolean allocateLeft, RLESparseResourceAllocation allocations) { - return algStageEarliestStart.setEarliestStartTime(plan, reservation, index, - currentReservationStage, stageDeadline); + return algStageExecutionInterval.computeExecutionInterval(plan, reservation, + currentReservationStage, allocateLeft, allocations); } // Call algStageAllocator protected Map computeStageAllocation( Plan plan, ReservationRequest rr, long stageArrivalTime, - long stageDeadline, String user, ReservationId oldId) - throws PlanningException { + long stageDeadline, String user, ReservationId oldId) throws PlanningException { return algStageAllocator.computeStageAllocation(plan, planLoads, planModifications, rr, stageArrivalTime, stageDeadline, user, oldId); } - // Set the algorithm: algStageEarliestStart - public IterativePlanner setAlgStageEarliestStart(StageEarliestStart alg) { + // Set the algorithm: algStageExecutionInterval + public IterativePlanner setAlgStageExecutionInterval(StageExecutionInterval alg) { - this.algStageEarliestStart = alg; + this.algStageExecutionInterval = alg; return this; // To allow concatenation of setAlg() functions } @@ -365,20 +347,14 @@ public IterativePlanner setAlgStageAllocator(StageAllocator alg) { return this; // To allow concatenation of setAlg() functions } - - /** - * Helper class that provide a list of ReservationRequests and iterates - * forward or backward depending whether we are allocating left-to-right or - * right-to-left. - */ + public static class StageProvider { private final boolean allocateLeft; private ListIterator li; - public StageProvider(boolean allocateLeft, - ReservationDefinition reservation) { + public StageProvider(boolean allocateLeft, ReservationDefinition reservation) { this.allocateLeft = allocateLeft; int startingIndex; @@ -395,25 +371,25 @@ public StageProvider(boolean allocateLeft, .listIterator(startingIndex); } - - public boolean hasNext() { - if (allocateLeft) { + + public boolean hasNext(){ + if(allocateLeft){ return li.hasNext(); } else { return li.hasPrevious(); } } - - public ReservationRequest next() { - if (allocateLeft) { + + public ReservationRequest next(){ + if(allocateLeft) { return li.next(); } else { return li.previous(); - } + } } - - public int getCurrentIndex() { - if (allocateLeft) { + + public int getCurrentIndex(){ + if(allocateLeft){ return li.nextIndex() - 1; } else { return li.previousIndex() + 1; diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/PlanningAlgorithm.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/PlanningAlgorithm.java index e1b508d..ecf1871 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/PlanningAlgorithm.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/PlanningAlgorithm.java @@ -129,8 +129,8 @@ protected boolean allocateUser(ReservationId reservationId, String user, } public abstract RLESparseResourceAllocation computeJobAllocation(Plan plan, - ReservationId reservationId, ReservationDefinition reservation, - String user) throws PlanningException, ContractValidationException; + ReservationId reservationId, ReservationDefinition reservation, String user) + throws PlanningException, ContractValidationException; @Override public boolean createReservation(ReservationId reservationId, String user, @@ -162,8 +162,7 @@ public boolean deleteReservation(ReservationId reservationId, String user, } - protected static long findEarliestTime( - Map sesInt) { + protected static long findEarliestTime(Map sesInt) { long ret = Long.MAX_VALUE; for (Entry s : sesInt.entrySet()) { @@ -175,8 +174,7 @@ protected static long findEarliestTime( } - protected static long findLatestTime(Map sesInt) { + protected static long findLatestTime(Map sesInt) { long ret = Long.MIN_VALUE; for (Entry s : sesInt.entrySet()) { diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageAllocator.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageAllocator.java index b95f8d4..d426fd5 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageAllocator.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageAllocator.java @@ -41,19 +41,21 @@ * @param planModifications the allocations performed by the planning * algorithm which are not yet reflected by plan * @param rr the stage - * @param stageEarliestStart the arrival time (earliest starting time) set for + * @param stageArrival the arrival time (earliest starting time) set for * the stage by the two phase planning algorithm * @param stageDeadline the deadline of the stage set by the two phase * planning algorithm + * @param user + * @param oldId * * @return The computed allocation (or null if the stage could not be * allocated) - * @throws PlanningException + * @throws PlanningException */ Map computeStageAllocation(Plan plan, - Map planLoads, + RLESparseResourceAllocation planLoads, RLESparseResourceAllocation planModifications, ReservationRequest rr, - long stageEarliestStart, long stageDeadline, String user, + long stageArrival, long stageDeadline, String user, ReservationId oldId) throws PlanningException; } \ No newline at end of file diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageAllocatorGreedy.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageAllocatorGreedy.java index c836970..e246e69 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageAllocatorGreedy.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageAllocatorGreedy.java @@ -41,7 +41,7 @@ @Override public Map computeStageAllocation(Plan plan, - Map planLoads, + RLESparseResourceAllocation planLoads, RLESparseResourceAllocation planModifications, ReservationRequest rr, long stageEarliestStart, long stageDeadline, String user, ReservationId oldId) throws PlanningException { diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageAllocatorGreedyRLE.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageAllocatorGreedyRLE.java index c5a3192..f8adaca 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageAllocatorGreedyRLE.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageAllocatorGreedyRLE.java @@ -52,7 +52,7 @@ public StageAllocatorGreedyRLE(boolean allocateLeft) { @Override public Map computeStageAllocation(Plan plan, - Map planLoads, + RLESparseResourceAllocation planLoads, RLESparseResourceAllocation planModifications, ReservationRequest rr, long stageEarliestStart, long stageDeadline, String user, ReservationId oldId) throws PlanningException { diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageAllocatorLowCostAligned.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageAllocatorLowCostAligned.java index b9fd8e1..54c835a 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageAllocatorLowCostAligned.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageAllocatorLowCostAligned.java @@ -18,8 +18,12 @@ package org.apache.hadoop.yarn.server.resourcemanager.reservation.planning; +import java.util.ArrayList; import java.util.Comparator; +import java.util.List; import java.util.Map; +import java.util.Map.Entry; +import java.util.NavigableMap; import java.util.TreeSet; import org.apache.hadoop.yarn.api.records.ReservationId; @@ -28,45 +32,55 @@ import org.apache.hadoop.yarn.server.resourcemanager.reservation.Plan; import org.apache.hadoop.yarn.server.resourcemanager.reservation.RLESparseResourceAllocation; import org.apache.hadoop.yarn.server.resourcemanager.reservation.ReservationInterval; +import org.apache.hadoop.yarn.server.resourcemanager.reservation.RLESparseResourceAllocation.RLEOperator; +import org.apache.hadoop.yarn.server.resourcemanager.reservation.exceptions.PlanningException; import org.apache.hadoop.yarn.util.resource.ResourceCalculator; import org.apache.hadoop.yarn.util.resource.Resources; /** * A stage allocator that iteratively allocates containers in the * {@link DurationInterval} with lowest overall cost. The algorithm only - * considers intervals of the form: [stageDeadline - (n+1)*duration, - * stageDeadline - n*duration) for an integer n. This guarantees that the - * allocations are aligned (as opposed to overlapping duration intervals). - * - * The smoothnessFactor parameter controls the number of containers that are - * simultaneously allocated in each iteration of the algorithm. + * considers non-overlapping intervals of length 'duration'. This guarantees + * that the allocations are aligned. If 'allocateLeft == true', the intervals + * considered by the algorithm are aligned to stageArrival; otherwise, they are + * aligned to stageDeadline. The smoothnessFactor parameter controls the number + * of containers that are simultaneously allocated in each iteration of the + * algorithm. */ public class StageAllocatorLowCostAligned implements StageAllocator { + private final boolean allocateLeft; // Smoothness factor private int smoothnessFactor = 10; // Constructor - public StageAllocatorLowCostAligned() { + public StageAllocatorLowCostAligned(boolean allocateLeft) { + this.allocateLeft = allocateLeft; } // Constructor - public StageAllocatorLowCostAligned(int smoothnessFactor) { + public StageAllocatorLowCostAligned(int smoothnessFactor, boolean allocateLeft) { + this.allocateLeft = allocateLeft; this.smoothnessFactor = smoothnessFactor; } - // computeJobAllocation() + // computeStageAllocation() @Override - public Map computeStageAllocation( - Plan plan, Map planLoads, + public Map computeStageAllocation(Plan plan, + RLESparseResourceAllocation planLoads, RLESparseResourceAllocation planModifications, ReservationRequest rr, - long stageEarliestStart, long stageDeadline, String user, - ReservationId oldId) { + long stageArrival, long stageDeadline, String user, ReservationId oldId) + throws PlanningException { // Initialize ResourceCalculator resCalc = plan.getResourceCalculator(); Resource capacity = plan.getTotalCapacity(); + + RLESparseResourceAllocation netRLERes = + plan.getAvailableResourceOverTime(user, oldId, stageArrival, + stageDeadline); + long step = plan.getStep(); // Create allocationRequestsearlies @@ -76,7 +90,7 @@ public StageAllocatorLowCostAligned(int smoothnessFactor) { // Initialize parameters long duration = stepRoundUp(rr.getDuration(), step); int windowSizeInDurations = - (int) ((stageDeadline - stageEarliestStart) / duration); + (int) ((stageDeadline - stageArrival) / duration); int totalGangs = rr.getNumContainers() / rr.getConcurrency(); int numContainersPerGang = rr.getConcurrency(); Resource gang = @@ -93,6 +107,8 @@ public StageAllocatorLowCostAligned(int smoothnessFactor) { return null; } + final int preferLeft = allocateLeft ? 1 : -1; + // Initialize tree sorted by costs TreeSet durationIntervalsSortedByCost = new TreeSet(new Comparator() { @@ -104,23 +120,27 @@ public int compare(DurationInterval val1, DurationInterval val2) { return cmp; } - return (-1) * Long.compare(val1.getEndTime(), val2.getEndTime()); + return preferLeft + * Long.compare(val1.getEndTime(), val2.getEndTime()); } }); + List intervalEndTimes = + computeIntervalEndTimes(stageArrival, stageDeadline, duration, + allocateLeft); + // Add durationIntervals that end at (endTime - n*duration) for some n. - for (long intervalEnd = stageDeadline; intervalEnd >= stageEarliestStart - + duration; intervalEnd -= duration) { + for (long intervalEnd : intervalEndTimes) { long intervalStart = intervalEnd - duration; // Get duration interval [intervalStart,intervalEnd) DurationInterval durationInterval = getDurationInterval(intervalStart, intervalEnd, planLoads, - planModifications, capacity, resCalc, step); + planModifications, capacity, netRLERes, resCalc, step, gang); // If the interval can fit a gang, add it to the tree - if (durationInterval.canAllocate(gang, capacity, resCalc)) { + if (durationInterval.canAllocate()) { durationIntervalsSortedByCost.add(durationInterval); } } @@ -139,8 +159,7 @@ public int compare(DurationInterval val1, DurationInterval val2) { durationIntervalsSortedByCost.first(); int numGangsToAllocate = Math.min(maxGangsPerUnit, remainingGangs); numGangsToAllocate = - Math.min(numGangsToAllocate, - bestDurationInterval.numCanFit(gang, capacity, resCalc)); + Math.min(numGangsToAllocate, bestDurationInterval.numCanFit()); // Add it remainingGangs -= numGangsToAllocate; @@ -162,10 +181,10 @@ public int compare(DurationInterval val1, DurationInterval val2) { DurationInterval updatedDurationInterval = getDurationInterval(bestDurationInterval.getStartTime(), bestDurationInterval.getStartTime() + duration, planLoads, - planModifications, capacity, resCalc, step); + planModifications, capacity, netRLERes, resCalc, step, gang); // Add to tree, if possible - if (updatedDurationInterval.canAllocate(gang, capacity, resCalc)) { + if (updatedDurationInterval.canAllocate()) { durationIntervalsSortedByCost.add(updatedDurationInterval); } @@ -180,10 +199,12 @@ public int compare(DurationInterval val1, DurationInterval val2) { return allocations; } else { - // If we are here is because we did not manage to satisfy this request. - // We remove unwanted side-effect from planModifications (needed for ANY). - for (Map.Entry tempAllocation - : allocations.entrySet()) { + // If we are here is because we did not manage to satisfy this + // request. + // We remove unwanted side-effect from planModifications (needed for + // ANY). + for (Map.Entry tempAllocation : allocations + .entrySet()) { planModifications.removeInterval(tempAllocation.getKey(), tempAllocation.getValue()); @@ -196,45 +217,118 @@ public int compare(DurationInterval val1, DurationInterval val2) { } + private List computeIntervalEndTimes(long stageEarliestStart, + long stageDeadline, long duration, boolean allocateLeft) { + + List intervalEndTimes = new ArrayList(); + if (!allocateLeft) { + + for (long intervalEnd = stageDeadline; intervalEnd >= stageEarliestStart + + duration; intervalEnd -= duration) { + intervalEndTimes.add(intervalEnd); + } + } else { + + for (long intervalStart = stageEarliestStart; intervalStart <= stageDeadline + - duration; intervalStart += duration) { + intervalEndTimes.add(intervalStart + duration); + } + } + + return intervalEndTimes; + } + protected DurationInterval getDurationInterval(long startTime, long endTime, - Map planLoads, + RLESparseResourceAllocation planLoads, RLESparseResourceAllocation planModifications, Resource capacity, - ResourceCalculator resCalc, long step) { + RLESparseResourceAllocation netRLERes, ResourceCalculator resCalc, + long step, Resource requestedResources) throws PlanningException { // Initialize the dominant loads structure Resource dominantResources = Resource.newInstance(0, 0); + int gangsCanFit = Integer.MAX_VALUE; + int curGangsCanFit; - // Calculate totalCost and maxLoad double totalCost = 0.0; - for (long t = startTime; t < endTime; t += step) { - // Get the load - Resource load = getLoadAtTime(t, planLoads, planModifications); + RLESparseResourceAllocation currentLoad = + RLESparseResourceAllocation.merge(resCalc, capacity, planLoads, + planModifications, RLEOperator.add, startTime, endTime); - // Increase the total cost - totalCost += calcCostOfLoad(load, capacity, resCalc); + NavigableMap mapCurrentLoad = currentLoad.getCumulative(); - // Update the dominant resources - dominantResources = Resources.componentwiseMax(dominantResources, load); + // Calculate the cost of the duration interval + Long tPrev = -1L; + Resource loadPrev = Resources.none(); + double cost = 0.0; + + for (Entry e : mapCurrentLoad.entrySet()) { + Long t = e.getKey(); + Resource load = e.getValue(); + if (tPrev != -1L) { + tPrev = Math.max(tPrev, startTime); + cost = calcCostOfLoad(loadPrev, capacity, resCalc); + totalCost = totalCost + cost * (t - tPrev) / step; + } + tPrev = t; + loadPrev = load; + } + + // compute the cost for the last interval + if (loadPrev != null) { + // this takes care of the corner case of a single entry + tPrev = Math.max(tPrev, startTime); + cost = calcCostOfLoad(loadPrev, capacity, resCalc); + totalCost = totalCost + cost * (endTime - tPrev) / step; + } + + // now we calculate how many gangs can fit in the DurationInterval. For + // the available resources, + // we take what the sharing policy gives us, and subtract the + // planModification (of the current job) + RLESparseResourceAllocation netAvailableResources = + RLESparseResourceAllocation.merge(resCalc, capacity, netRLERes, + planModifications, RLEOperator.subtract, startTime, endTime); + + NavigableMap mapAvailableCapacity = + netAvailableResources.getCumulative(); + + for (Entry e : mapAvailableCapacity.entrySet()) { + Long t = e.getKey(); + Resource curAvailable = e.getValue(); + if (t >= endTime) + break; + + if (curAvailable == null) { + gangsCanFit = 0; + + } else { + + curGangsCanFit = + (int) Math.floor(Resources.divide(resCalc, capacity, curAvailable, + requestedResources)); + if (curGangsCanFit < gangsCanFit) + gangsCanFit = curGangsCanFit; + } } // Return the corresponding durationInterval return new DurationInterval(startTime, endTime, totalCost, - dominantResources); + dominantResources, gangsCanFit); } protected double calcCostOfInterval(long startTime, long endTime, - Map planLoads, + RLESparseResourceAllocation planLoads, RLESparseResourceAllocation planModifications, Resource capacity, ResourceCalculator resCalc, long step) { // Sum costs in the interval [startTime,endTime) double totalCost = 0.0; for (long t = startTime; t < endTime; t += step) { - totalCost += calcCostOfTimeSlot(t, planLoads, planModifications, capacity, - resCalc); + totalCost += + calcCostOfTimeSlot(t, planLoads, planModifications, capacity, resCalc); } // Return sum @@ -242,7 +336,8 @@ protected double calcCostOfInterval(long startTime, long endTime, } - protected double calcCostOfTimeSlot(long t, Map planLoads, + protected double calcCostOfTimeSlot(long t, + RLESparseResourceAllocation planLoads, RLESparseResourceAllocation planModifications, Resource capacity, ResourceCalculator resCalc) { @@ -254,11 +349,13 @@ protected double calcCostOfTimeSlot(long t, Map planLoads, } - protected Resource getLoadAtTime(long t, Map planLoads, + protected Resource getLoadAtTime(long t, + RLESparseResourceAllocation planLoads, RLESparseResourceAllocation planModifications) { - Resource planLoad = planLoads.get(t); - planLoad = (planLoad == null) ? Resource.newInstance(0, 0) : planLoad; + Resource planLoad = planLoads.getCapacityAtTime(t); + // planLoad = (planLoad == null) ? Resource.newInstance(0, 0) : + // planLoad; return Resources.add(planLoad, planModifications.getCapacityAtTime(t)); @@ -290,41 +387,31 @@ protected static long stepRoundUp(long t, long step) { private long endTime; private double cost; private Resource maxLoad; + private int gangsCanFit; // Constructor public DurationInterval(long startTime, long endTime, double cost, - Resource maxLoad) { + Resource maxLoad, int gangsCanfit) { this.startTime = startTime; this.endTime = endTime; this.cost = cost; this.maxLoad = maxLoad; + this.gangsCanFit = gangsCanfit; } // canAllocate() - boolean function, returns whether requestedResources // can be allocated during the durationInterval without // violating capacity constraints - public boolean canAllocate(Resource requestedResources, Resource capacity, - ResourceCalculator resCalc) { - - Resource updatedMaxLoad = Resources.add(maxLoad, requestedResources); - return (resCalc.compare(capacity, updatedMaxLoad, capacity) <= 0); - + public boolean canAllocate() { + return (gangsCanFit > 0); } // numCanFit() - returns the maximal number of requestedResources can be // allocated during the durationInterval without violating // capacity constraints - public int numCanFit(Resource requestedResources, Resource capacity, - ResourceCalculator resCalc) { - - // Represents the largest resource demand that can be satisfied throughout - // the entire DurationInterval (i.e., during [startTime,endTime)) - Resource availableResources = Resources.subtract(capacity, maxLoad); - - // Maximal number of requestedResources that fit inside the interval - return (int) Math.floor(Resources.divide(resCalc, capacity, - availableResources, requestedResources)); + public int numCanFit() { + return gangsCanFit; } public long getStartTime() { @@ -360,10 +447,16 @@ public void setTotalCost(double value) { } public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(" start: " + startTime).append(" end: " + endTime) - .append(" cost: " + cost).append(" maxLoad: " + maxLoad); + .append(" cost: " + cost).append(" maxLoad: " + maxLoad) + .append(" gangsCanFit: " + gangsCanFit); + return sb.toString(); + } + } } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageEarliestStart.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageEarliestStart.java deleted file mode 100644 index 547616a..0000000 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageEarliestStart.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hadoop.yarn.server.resourcemanager.reservation.planning; - -import org.apache.hadoop.yarn.api.records.ReservationDefinition; -import org.apache.hadoop.yarn.api.records.ReservationRequest; -import org.apache.hadoop.yarn.server.resourcemanager.reservation.Plan; - -/** - * Interface for setting the earliest start time of a stage in IterativePlanner. - */ -public interface StageEarliestStart { - - /** - * Computes the earliest allowed starting time for a given stage. - * - * @param plan the Plan to which the reservation must be fitted - * @param reservation the job contract - * @param index the index of the stage in the job contract - * @param currentReservationStage the stage - * @param stageDeadline the deadline of the stage set by the two phase - * planning algorithm - * - * @return the earliest allowed starting time for the stage. - */ - long setEarliestStartTime(Plan plan, ReservationDefinition reservation, - int index, ReservationRequest currentReservationStage, - long stageDeadline); - -} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageEarliestStartByDemand.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageEarliestStartByDemand.java deleted file mode 100644 index 5a46a4e..0000000 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageEarliestStartByDemand.java +++ /dev/null @@ -1,106 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hadoop.yarn.server.resourcemanager.reservation.planning; - -import java.util.ListIterator; - -import org.apache.hadoop.yarn.api.records.ReservationDefinition; -import org.apache.hadoop.yarn.api.records.ReservationRequest; -import org.apache.hadoop.yarn.server.resourcemanager.reservation.Plan; - -/** - * Sets the earliest start time of a stage proportional to the job weight. The - * interval [jobArrival, stageDeadline) is divided as follows. First, each stage - * is guaranteed at least its requested duration. Then, the stage receives a - * fraction of the remaining time. The fraction is calculated as the ratio - * between the weight (total requested resources) of the stage and the total - * weight of all proceeding stages. - */ - -public class StageEarliestStartByDemand implements StageEarliestStart { - - private long step; - - @Override - public long setEarliestStartTime(Plan plan, - ReservationDefinition reservation, int index, ReservationRequest current, - long stageDeadline) { - - step = plan.getStep(); - - // If this is the first stage, don't bother with the computation. - if (index < 1) { - return reservation.getArrival(); - } - - // Get iterator - ListIterator li = - reservation.getReservationRequests().getReservationResources() - .listIterator(index); - ReservationRequest rr; - - // Calculate the total weight & total duration - double totalWeight = calcWeight(current); - long totalDuration = getRoundedDuration(current, plan); - - while (li.hasPrevious()) { - rr = li.previous(); - totalWeight += calcWeight(rr); - totalDuration += getRoundedDuration(rr, plan); - } - - // Compute the weight of the current stage as compared to remaining ones - double ratio = calcWeight(current) / totalWeight; - - // Estimate an early start time, such that: - // 1. Every stage is guaranteed to receive at least its duration - // 2. The remainder of the window is divided between stages - // proportionally to its workload (total memory consumption) - long window = stageDeadline - reservation.getArrival(); - long windowRemainder = window - totalDuration; - long earlyStart = - (long) (stageDeadline - getRoundedDuration(current, plan) - - (windowRemainder * ratio)); - - // Realign if necessary (since we did some arithmetic) - earlyStart = stepRoundUp(earlyStart, step); - - // Return - return earlyStart; - - } - - // Weight = total memory consumption of stage - protected double calcWeight(ReservationRequest stage) { - return (stage.getDuration() * stage.getCapability().getMemory()) - * (stage.getNumContainers()); - } - - protected long getRoundedDuration(ReservationRequest stage, Plan plan) { - return stepRoundUp(stage.getDuration(), step); - } - - protected static long stepRoundDown(long t, long step) { - return (t / step) * step; - } - - protected static long stepRoundUp(long t, long step) { - return ((t + step - 1) / step) * step; - } -} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageEarliestStartByJobArrival.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageEarliestStartByJobArrival.java deleted file mode 100644 index 8347816..0000000 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/StageEarliestStartByJobArrival.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hadoop.yarn.server.resourcemanager.reservation.planning; - -import org.apache.hadoop.yarn.api.records.ReservationDefinition; -import org.apache.hadoop.yarn.api.records.ReservationRequest; -import org.apache.hadoop.yarn.server.resourcemanager.reservation.Plan; - -/** - * Sets the earliest start time of a stage as the job arrival time. - */ -public class StageEarliestStartByJobArrival implements StageEarliestStart { - - @Override - public long setEarliestStartTime(Plan plan, - ReservationDefinition reservation, int index, ReservationRequest current, - long stageDeadline) { - - return reservation.getArrival(); - - } - -} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/TestAlignedPlanner.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/TestAlignedPlanner.java index ec305a2..da44709 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/TestAlignedPlanner.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/planning/TestAlignedPlanner.java @@ -107,7 +107,7 @@ public void testOrderNoGapImpossible() throws PlanningException { // Create reservation ReservationDefinition rr1 = createReservationDefinition( - 10L, // Job arrival time + 10 * step, // Job arrival time 15 * step, // Job deadline new ReservationRequest[] { ReservationRequest.newInstance(