[haizea-commit] r585 - in branches/TP2.0/src/haizea/resourcemanager: . scheduler
haizea-commit at mailman.cs.uchicago.edu
haizea-commit at mailman.cs.uchicago.edu
Wed Jun 17 11:09:35 CDT 2009
Author: borja
Date: 2009-06-17 11:09:33 -0500 (Wed, 17 Jun 2009)
New Revision: 585
Modified:
branches/TP2.0/src/haizea/resourcemanager/rm.py
branches/TP2.0/src/haizea/resourcemanager/scheduler/lease_scheduler.py
branches/TP2.0/src/haizea/resourcemanager/scheduler/vm_scheduler.py
Log:
Pushing minor changes before renaming "resourcemanager" package
Modified: branches/TP2.0/src/haizea/resourcemanager/rm.py
===================================================================
--- branches/TP2.0/src/haizea/resourcemanager/rm.py 2009-06-17 15:29:09 UTC (rev 584)
+++ branches/TP2.0/src/haizea/resourcemanager/rm.py 2009-06-17 16:09:33 UTC (rev 585)
@@ -45,6 +45,7 @@
from haizea.resourcemanager.scheduler.lease_scheduler import LeaseScheduler
from haizea.resourcemanager.scheduler.vm_scheduler import VMScheduler
from haizea.resourcemanager.scheduler.slottable import SlotTable
+from haizea.resourcemanager.scheduler.policy import Policy
from haizea.resourcemanager.scheduler.resourcepool import ResourcePool, ResourcePoolWithReusableImages
from haizea.resourcemanager.rpcserver import RPCServer
from haizea.common.utils import abstract, round_datetime, Singleton
@@ -153,6 +154,9 @@
# Lease Scheduler
self.scheduler = LeaseScheduler(vm_scheduler, preparation_scheduler, slottable)
+ # Policy engine
+ self.policy = Policy()
+
# Lease request frontends
if clock == constants.CLOCK_SIMULATED:
# In pure simulation, we can only use the tracefile frontend
Modified: branches/TP2.0/src/haizea/resourcemanager/scheduler/lease_scheduler.py
===================================================================
--- branches/TP2.0/src/haizea/resourcemanager/scheduler/lease_scheduler.py 2009-06-17 15:29:09 UTC (rev 584)
+++ branches/TP2.0/src/haizea/resourcemanager/scheduler/lease_scheduler.py 2009-06-17 16:09:33 UTC (rev 585)
@@ -42,30 +42,12 @@
"""The Haizea Lease Scheduler
This is the main scheduling class in Haizea. It handles lease scheduling which,
- in turn involved VM scheduling, preparation scheduling (such as transferring
+ in turn, involves VM scheduling, preparation scheduling (such as transferring
a VM image), and numerous bookkeeping operations. All these operations are
handled by other classes, so this class acts mostly as an orchestrator that
- coordinates all the different operations involved in scheduling a lease.
-
- Public methods:
- request_lease -- Entry point of leases into the scheduler
- schedule -- The scheduling function
- process_reservations -- Processes starting/ending reservations at a given time
- cancel_lease -- Cancels a lease
- fail_lease -- Marks a lease as failed, and does any necessary cleaning up
- is_queue_empty -- Is the queue empty?
- exists_scheduled_leases -- Are there any leases scheduled?
-
- Private methods:
- __process_queue -- Processes queue and, if possible, schedules leases
- __schedule_lease -- Schedules a lease
- __preempt_lease -- Preempts a lease
- __enqueue -- Puts a lease at the end of the queue
- __enqueue_in_order -- Queues a lease in order (currently, time of submission)
- _handle_end_rr -- Code that has to be run when a reservation ends
- _handle_end_lease -- Code that has to be run at the end of a lease
-
+ coordinates all the different operations involved in scheduling a lease.
"""
+
def __init__(self, vm_scheduler, preparation_scheduler, slottable):
"""Constructor
@@ -469,13 +451,8 @@
else:
raise InconsistentLeaseStateError(lease, doing = "scheduling a best-effort lease")
- if isinstance(lease, BestEffortLease):
- (vmrr, preemptions) = self.vm_scheduler.fit_asap(lease, nexttime, earliest)
- elif isinstance(lease, ARLease):
- (vmrr, preemptions) = self.vm_scheduler.fit_exact(lease, preemptible=False, canpreempt=True)
- elif isinstance(lease, ImmediateLease):
- (vmrr, preemptions) = self.vm_scheduler.fit_asap(lease, nexttime, earliest, allow_reservation_in_future=False)
-
+ (vmrr, preemptions) = self.vm_scheduler.schedule(lease, nextttime, earliest)
+
if len(preemptions) > 0:
self.logger.info("Must preempt leases %s to make room for lease #%i" % ([l.id for l in preemptions], lease.id))
for l in preemptions:
Modified: branches/TP2.0/src/haizea/resourcemanager/scheduler/vm_scheduler.py
===================================================================
--- branches/TP2.0/src/haizea/resourcemanager/scheduler/vm_scheduler.py 2009-06-17 15:29:09 UTC (rev 584)
+++ branches/TP2.0/src/haizea/resourcemanager/scheduler/vm_scheduler.py 2009-06-17 16:09:33 UTC (rev 585)
@@ -77,7 +77,15 @@
self.numbesteffortres = 0
- def fit_exact(self, leasereq, preemptible=False, canpreempt=True, avoidpreempt=True):
+ def schedule(self, lease, nexttime, earliest):
+ if isinstance(lease, BestEffortLease):
+ (vmrr, preemptions) = self.vm_scheduler.fit_asap(lease, nexttime, earliest)
+ elif isinstance(lease, ARLease):
+ (vmrr, preemptions) = self.vm_scheduler.fit_exact(lease, preemptible=False, canpreempt=True)
+ elif isinstance(lease, ImmediateLease):
+ (vmrr, preemptions) = self.vm_scheduler.fit_asap(lease, nexttime, earliest, allow_reservation_in_future=False)
+
+ def fit(self, requested_resources, start, end, strictend):
lease_id = leasereq.id
start = leasereq.start.requested
end = leasereq.start.requested + leasereq.duration.requested + self.__estimate_shutdown_time(leasereq)
@@ -556,7 +564,7 @@
def get_utilization(self, time):
total = self.slottable.get_total_capacity()
util = {}
- reservations = self.slottable.getReservationsAt(time)
+ reservations = self.slottable.get_reservations_at(time)
for r in reservations:
for node in r.resources_in_pnode:
if isinstance(r, VMResourceReservation):
@@ -913,185 +921,7 @@
threshold = safe_duration + (min_duration * factor)
return threshold
- def __find_preemptable_leases(self, mustpreempt, startTime, endTime):
- def comparepreemptability(rrX, rrY):
- if rrX.lease.submit_time > rrY.lease.submit_time:
- return constants.BETTER
- elif rrX.lease.submit_time < rrY.lease.submit_time:
- return constants.WORSE
- else:
- return constants.EQUAL
-
- def preemptedEnough(amountToPreempt):
- for node in amountToPreempt:
- if not amountToPreempt[node].is_zero_or_less():
- return False
- return True
-
- # Get allocations at the specified time
- atstart = set()
- atmiddle = set()
- nodes = set(mustpreempt.keys())
-
- reservationsAtStart = self.slottable.getReservationsAt(startTime)
- reservationsAtStart = [r for r in reservationsAtStart if isinstance(r, VMResourceReservation) and r.is_preemptible()
- and len(set(r.resources_in_pnode.keys()) & nodes)>0]
-
- reservationsAtMiddle = self.slottable.get_reservations_starting_between(startTime, endTime)
- reservationsAtMiddle = [r for r in reservationsAtMiddle if isinstance(r, VMResourceReservation) and r.is_preemptible()
- and len(set(r.resources_in_pnode.keys()) & nodes)>0]
-
- reservationsAtStart.sort(comparepreemptability)
- reservationsAtMiddle.sort(comparepreemptability)
-
- amountToPreempt = {}
- for n in mustpreempt:
- amountToPreempt[n] = ResourceTuple.copy(mustpreempt[n])
- # First step: CHOOSE RESOURCES TO PREEMPT AT START OF RESERVATION
- for r in reservationsAtStart:
- # The following will really only come into play when we have
- # multiple VMs per node
- mustpreemptres = False
- for n in r.resources_in_pnode.keys():
- # Don't need to preempt if we've already preempted all
- # the needed resources in node n
- if amountToPreempt.has_key(n) and not amountToPreempt[n].is_zero_or_less():
- amountToPreempt[n].decr(r.resources_in_pnode[n])
- mustpreemptres = True
- if mustpreemptres:
- atstart.add(r)
- if preemptedEnough(amountToPreempt):
- break
-
- # Second step: CHOOSE RESOURCES TO PREEMPT DURING RESERVATION
- if len(reservationsAtMiddle)>0:
- changepoints = set()
- for r in reservationsAtMiddle:
- changepoints.add(r.start)
- changepoints = list(changepoints)
- changepoints.sort()
-
- for cp in changepoints:
- amountToPreempt = {}
- for n in mustpreempt:
- amountToPreempt[n] = ResourceTuple.copy(mustpreempt[n])
- reservations = [r for r in reservationsAtMiddle
- if r.start <= cp and cp < r.end]
- for r in reservations:
- mustpreemptres = False
- for n in r.resources_in_pnode.keys():
- if amountToPreempt.has_key(n) and not amountToPreempt[n].is_zero_or_less():
- amountToPreempt[n].decr(r.resources_in_pnode[n])
- mustpreemptres = True
- if mustpreemptres:
- atmiddle.add(r)
- if preemptedEnough(amountToPreempt):
- break
-
- self.logger.debug("Preempting leases (at start of reservation): %s" % [r.lease.id for r in atstart])
- self.logger.debug("Preempting leases (in middle of reservation): %s" % [r.lease.id for r in atmiddle])
-
- leases = [r.lease for r in atstart|atmiddle]
-
- return leases
-
-
- def __choose_nodes(self, canfit, start, canpreempt, avoidpreempt):
- # TODO2: Choose appropriate prioritizing function based on a
- # config file, instead of hardcoding it)
- #
- # TODO3: Basing decisions only on CPU allocations. This is ok for now,
- # since the memory allocation is proportional to the CPU allocation.
- # Later on we need to come up with some sort of weighed average.
-
- nodes = canfit.keys()
-
- # TODO: The deployment module should just provide a list of nodes
- # it prefers
- nodeswithimg=[]
- #self.lease_deployment_type = get_config().get("lease-preparation")
- #if self.lease_deployment_type == constants.DEPLOYMENT_TRANSFER:
- # reusealg = get_config().get("diskimage-reuse")
- # if reusealg==constants.REUSE_IMAGECACHES:
- # nodeswithimg = self.resourcepool.getNodesWithImgInPool(diskImageID, start)
-
- # Compares node x and node y.
- # Returns "x is ??? than y" (???=BETTER/WORSE/EQUAL)
- def comparenodes(x, y):
- hasimgX = x in nodeswithimg
- hasimgY = y in nodeswithimg
-
- # First comparison: A node with no preemptible VMs is preferible
- # to one with preemptible VMs (i.e. we want to avoid preempting)
- canfitnopreemptionX = canfit[x][0]
- canfitpreemptionX = canfit[x][1]
- hasPreemptibleX = canfitpreemptionX > canfitnopreemptionX
-
- canfitnopreemptionY = canfit[y][0]
- canfitpreemptionY = canfit[y][1]
- hasPreemptibleY = canfitpreemptionY > canfitnopreemptionY
-
- # TODO: Factor out common code
- if avoidpreempt:
- if hasPreemptibleX and not hasPreemptibleY:
- return constants.WORSE
- elif not hasPreemptibleX and hasPreemptibleY:
- return constants.BETTER
- elif not hasPreemptibleX and not hasPreemptibleY:
- if hasimgX and not hasimgY:
- return constants.BETTER
- elif not hasimgX and hasimgY:
- return constants.WORSE
- else:
- if canfitnopreemptionX > canfitnopreemptionY: return constants.BETTER
- elif canfitnopreemptionX < canfitnopreemptionY: return constants.WORSE
- else: return constants.EQUAL
- elif hasPreemptibleX and hasPreemptibleY:
- # If both have (some) preemptible resources, we prefer those
- # that involve the less preemptions
- preemptX = canfitpreemptionX - canfitnopreemptionX
- preemptY = canfitpreemptionY - canfitnopreemptionY
- if preemptX < preemptY:
- return constants.BETTER
- elif preemptX > preemptY:
- return constants.WORSE
- else:
- if hasimgX and not hasimgY: return constants.BETTER
- elif not hasimgX and hasimgY: return constants.WORSE
- else: return constants.EQUAL
- elif not avoidpreempt:
- # First criteria: Can we reuse image?
- if hasimgX and not hasimgY:
- return constants.BETTER
- elif not hasimgX and hasimgY:
- return constants.WORSE
- else:
- # Now we just want to avoid preemption
- if hasPreemptibleX and not hasPreemptibleY:
- return constants.WORSE
- elif not hasPreemptibleX and hasPreemptibleY:
- return constants.BETTER
- elif hasPreemptibleX and hasPreemptibleY:
- # If both have (some) preemptible resources, we prefer those
- # that involve the less preemptions
- preemptX = canfitpreemptionX - canfitnopreemptionX
- preemptY = canfitpreemptionY - canfitnopreemptionY
- if preemptX < preemptY:
- return constants.BETTER
- elif preemptX > preemptY:
- return constants.WORSE
- else:
- if hasimgX and not hasimgY: return constants.BETTER
- elif not hasimgX and hasimgY: return constants.WORSE
- else: return constants.EQUAL
- else:
- return constants.EQUAL
-
- # Order nodes
- nodes.sort(comparenodes)
- return nodes
-
#-------------------------------------------------------------------#
# #
# SLOT TABLE EVENT HANDLERS #
More information about the Haizea-commit
mailing list