From b81e8bdae909ef0d6633ec0390f69de259181c79 Mon Sep 17 00:00:00 2001 From: Someone Date: Thu, 6 Jun 2013 22:16:03 +0200 Subject: [PATCH] SchedB now has Federation and Delaying of apps. --- .../ac/tuwien/lsdc/federation/Federation.java | 11 +- .../tuwien/lsdc/sched/AbstractScheduler.java | 173 +++++++++++------- src/at/ac/tuwien/lsdc/sched/SchedulerB.java | 86 ++++++++- .../ac/tuwien/lsdc/types/SchedulerEvent.java | 2 +- 4 files changed, 190 insertions(+), 82 deletions(-) diff --git a/src/at/ac/tuwien/lsdc/federation/Federation.java b/src/at/ac/tuwien/lsdc/federation/Federation.java index adf16f8..78cf678 100644 --- a/src/at/ac/tuwien/lsdc/federation/Federation.java +++ b/src/at/ac/tuwien/lsdc/federation/Federation.java @@ -1,5 +1,9 @@ package at.ac.tuwien.lsdc.federation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.ac.tuwien.lsdc.sched.SchedulerB; import at.ac.tuwien.lsdc.types.Application; /** @@ -10,10 +14,14 @@ import at.ac.tuwien.lsdc.types.Application; * */ public class Federation { + /** + * Logger. + */ + private static final Logger LOG = LoggerFactory.getLogger(SchedulerB.class); private int numPartners; public final static int fak = 100; - public final static int th = 20; + public final static int th = 30; public Federation(int numPartners) { this.numPartners = numPartners; @@ -27,6 +35,7 @@ public class Federation { * @return true, if application can be outsourced. */ public boolean askToOutsource(Application app) { + LOG.info("askToOutsource():" + app); for (int i = 0; i < numPartners; i++) { if (Math.random() * fak < th) return true; diff --git a/src/at/ac/tuwien/lsdc/sched/AbstractScheduler.java b/src/at/ac/tuwien/lsdc/sched/AbstractScheduler.java index 65ac7b7..f8aee45 100644 --- a/src/at/ac/tuwien/lsdc/sched/AbstractScheduler.java +++ b/src/at/ac/tuwien/lsdc/sched/AbstractScheduler.java @@ -9,22 +9,24 @@ import java.util.TreeMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import at.ac.tuwien.lsdc.federation.Federation; import at.ac.tuwien.lsdc.management.MachineManager; import at.ac.tuwien.lsdc.types.Application; import at.ac.tuwien.lsdc.types.ScenarioData; import at.ac.tuwien.lsdc.types.ScenarioType; import at.ac.tuwien.lsdc.types.SchedulerData; import at.ac.tuwien.lsdc.types.SchedulerEvent; -import at.ac.tuwien.lsdc.types.SchedulerType; import at.ac.tuwien.lsdc.types.SchedulerEvent.EventType; import at.ac.tuwien.lsdc.types.VirtualMachine.VMType; import at.ac.tuwien.lsdc.util.CSVLogger; import at.ac.tuwien.lsdc.util.NumberUtils; +/** + * Class doing all the generic scheduling work. + */ public abstract class AbstractScheduler { - private static final Logger log = LoggerFactory - .getLogger(AbstractScheduler.class); + private static final Logger log = LoggerFactory.getLogger(AbstractScheduler.class); // the following types are only needed for correct // log output @@ -40,52 +42,50 @@ public abstract class AbstractScheduler { protected CSVLogger logger; protected VMType vmType; - // this map saves the following Type of Events: - // start of an Application, end of an Application - // (start outSourced, end outSourced, start inSourced, end inSourced) + /** + * this map saves the following Type of Events: start of an Application, end + * of an Application(start outSourced, end outSourced, start inSourced, end + * inSourced) + */ protected SortedMap> eventMap; - // Scheduler has an internal Time "Abstraction" - // at every point in time it checks for Events in his "EventList" - // and handles them (via the individual scheduling algorithm) + /** + * Scheduler has an internal Time "Abstraction" at every point in time it + * checks for Events in his "EventList" and handles them (via the individual + * scheduling algorithm) + */ protected long currTime = 0; - // the timestamp at which the Scheduler is finished - // it is updated with every added "EndEvent" + /** + * the timestamp at which the Scheduler is finished it is updated with every + * added "EndEvent" + */ protected long endTime; - public AbstractScheduler(int numPMs, int numCloudPartners, - File schedulerLog, ScenarioType scenario) throws IOException { - this.manager = new MachineManager(numPMs); + /** + * All our cloud partners. + */ + protected Federation federation; + + public AbstractScheduler(int numPMs, int numCloudPartners, File schedulerLog, ScenarioType scenario) + throws IOException { + manager = new MachineManager(numPMs); this.schedulerLog = schedulerLog; this.scenario = scenario; - this.eventMap = new TreeMap>(); - this.logger = new CSVLogger(schedulerLog); - initCloudPartners(numCloudPartners); - - // Using federation ? - // federation = new Federation(numCloudPartners); + eventMap = new TreeMap>(); + logger = new CSVLogger(schedulerLog); + federation = new Federation(numCloudPartners); } - // intialize cloudpartners for federation - private void initCloudPartners(int numCloudPartners) { - for (int i = 0; i < numCloudPartners; i++) { - // initialize a cloudpartner - // add to a member: List - // CloudPartner should have 2 functions: - // insource & outsource - // insource randomly gives an application to us - // outsource accepts randomly applications from us - } - } - - // Initialize Scheduler with Data from CSV - // CSV will be parsed and sent as List to Scheduler + /** + * Initialize Scheduler with Data from CSV CSV will be parsed and sent as + * List to Scheduler + */ public ScenarioData initAndStart(LinkedList apps) { for (Application app : apps) { insertStartEvent(app.getTimestamp(), app); } - + endTime = apps.getLast().getTimestamp() + 1; startScheduling(); @@ -99,17 +99,37 @@ public abstract class AbstractScheduler { } /** - * Insert a start event into the map, at timestamp when the application - * should start - * + * Insert a start event into the map, at timestamp when the application should + * start + * * @param timestamp - * the timestamp when the application should start + * the timestamp when the application should start * @param app - * the application to start + * the application to start */ protected void insertStartEvent(long timestamp, Application app) { - SchedulerEvent evt = new SchedulerEvent(timestamp, - EventType.startApplication, app); + SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.startApplication, app); + if (!eventMap.containsKey(timestamp)) { + LinkedList list = new LinkedList(); + list.add(evt); + eventMap.put(timestamp, list); + } else { + LinkedList list = eventMap.get(timestamp); + list.add(evt); + } + } + + /** + * Insert a start outsourced event into the map, at timestamp when the + * application should start + * + * @param timestamp + * the timestamp when the application should start + * @param app + * the application to start + */ + protected void insertOutsourcedStartEvent(long timestamp, Application app) { + SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.startOutsourcedApplication, app); if (!eventMap.containsKey(timestamp)) { LinkedList list = new LinkedList(); list.add(evt); @@ -121,17 +141,40 @@ public abstract class AbstractScheduler { } /** - * Insert a stop event into the map, at timestamp when the application - * should stop - * + * Insert a stop event into the map, at timestamp when the application should + * stop. + * * @param timestamp - * the timestamp when the application should stop + * the timestamp when the application should stop * @param app - * the application to stop + * the application to stop */ protected void insertStopEvent(long timestamp, Application app) { - SchedulerEvent evt = new SchedulerEvent(timestamp, - EventType.endApplication, app); + SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.endApplication, app); + if (!eventMap.containsKey(timestamp)) { + LinkedList list = new LinkedList(); + list.add(evt); + eventMap.put(timestamp, list); + } else { + LinkedList list = eventMap.get(timestamp); + list.add(evt); + } + if (endTime < timestamp) { + endTime = timestamp; + } + } + + /** + * Insert a stop event into the map, at timestamp when the application should + * stop. + * + * @param timestamp + * the timestamp when the application should stop + * @param app + * the application to stop + */ + protected void insertOutsourcedStopEvent(long timestamp, Application app) { + SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.endOutsourcedApplication, app); if (!eventMap.containsKey(timestamp)) { LinkedList list = new LinkedList(); list.add(evt); @@ -153,7 +196,7 @@ public abstract class AbstractScheduler { while (true) { if (eventMap.containsKey(currTime)) { LinkedList events = eventMap.get(currTime); - // log.info(events.size() + " events at timestamp " + currTime); + // log.info(events.size() + " events at timestamp " + currTime); handleEvents(events); } doStateLogging(); @@ -171,9 +214,9 @@ public abstract class AbstractScheduler { /** * this method is where the Scheduling Algorithm resides it reads the Events * (start & stop of applications) - * + * * @param events - * the events to be read and used by the scheduler + * the events to be read and used by the scheduler */ protected abstract void handleEvents(LinkedList events); @@ -182,17 +225,9 @@ public abstract class AbstractScheduler { * directly to the specific scheduler/scenario csv file */ protected void doStateLogging() { - SchedulerData data = new SchedulerData( - currTime, - manager.getTotalRam(), - manager.getTotalCpu(), - manager.getTotalSize(), - manager.countCurrentlyRunningPMs(), - manager.countCurrentlyRunningVMs(), - manager.getCurrentConsumption(), - numCurrInSourced, - numCurrOutSourced - ); + SchedulerData data = new SchedulerData(currTime, manager.getTotalRam(), manager.getTotalCpu(), + manager.getTotalSize(), manager.countCurrentlyRunningPMs(), manager.countCurrentlyRunningVMs(), + manager.getCurrentConsumption(), numCurrInSourced, numCurrOutSourced); totalConsumption += manager.getCurrentConsumption(); try { logger.logSchedulerData(data); @@ -202,17 +237,15 @@ public abstract class AbstractScheduler { } /** - * this creates the total summary which should be written to a CSV at the - * end + * this creates the total summary which should be written to a CSV at the end * * @return a ScenarioData Object that holds the values to be logged */ protected ScenarioData doEndLogging() { - return new ScenarioData(getSchedulerType(), - scenario.toString(), manager.getTotalPMs(), manager.getTotalVMs(), endTime, NumberUtils.roundDouble(totalConsumption), numTotalInSourced, - numTotalOutSourced); + return new ScenarioData(getSchedulerType(), scenario.toString(), manager.getTotalPMs(), manager.getTotalVMs(), + endTime, NumberUtils.roundDouble(totalConsumption), numTotalInSourced, numTotalOutSourced); } - + protected abstract String getSchedulerType(); - + } diff --git a/src/at/ac/tuwien/lsdc/sched/SchedulerB.java b/src/at/ac/tuwien/lsdc/sched/SchedulerB.java index 6103406..b14540d 100644 --- a/src/at/ac/tuwien/lsdc/sched/SchedulerB.java +++ b/src/at/ac/tuwien/lsdc/sched/SchedulerB.java @@ -40,7 +40,11 @@ public class SchedulerB extends AbstractScheduler { */ private static final Logger LOG = LoggerFactory.getLogger(SchedulerB.class); - private final ArrayList delayedApps; + /** + * List of Apps that were delayed due to not enough free resources. TODO: move + * to abstractSched? + */ + private ArrayList delayedApps; public SchedulerB(int numPMs, int numCloudPartners, File schedulerLog, ScenarioType scenario) throws IOException { super(numPMs, numCloudPartners, schedulerLog, scenario); @@ -53,22 +57,83 @@ public class SchedulerB extends AbstractScheduler { protected void handleEvents(LinkedList events) { LOG.debug("handleEvents():" + events); handleEndEvents(events); - checkMigration(); - checkDelayedApps(); + handleOutsourcedEndEvents(events); + runMigration(); + runDelayedApps(); + handleOutsourcedStartEvents(events); handleStartEvents(events); } + /** + * handle running of outsourced apps. + * + * @param events + * list of all events that happened in this timeslot. + */ + private void handleOutsourcedStartEvents(LinkedList events) { + for (SchedulerEvent evt : events) { + if (evt.getType() == EventType.startOutsourcedApplication) { + insertOutsourcedStopEvent(currTime + evt.getApp().getDuration(), evt.getApp()); + numCurrOutSourced++; + numTotalOutSourced++; + } + } + } + + /** + * handle stopping of outsourced apps. + * + * @param events + * list of all events that happened in this timeslot. + */ + private void handleOutsourcedEndEvents(LinkedList events) { + for (SchedulerEvent evt : events) { + if (evt.getType() == EventType.endOutsourcedApplication) { + numCurrOutSourced--; + } + } + } + /** * Check if we have any delayed apps. Try to launch them. */ - private void checkDelayedApps() { - // TODO Auto-generated method stub + private void runDelayedApps() { + ArrayList newDelayedApps = new ArrayList(); + for (int i = 0; i < delayedApps.size(); i++) { + Application app = delayedApps.get(i); + VirtualMachine vm = null; + for (PhysicalMachine pm : manager.getPMs()) { + vm = pm.getVirtualMachines().get((pm.getVirtualMachines().keySet().toArray(new Integer[0]))[0]); + try { + vm.resizeVM(vm.getSize() + app.getSize(), vm.getRAM() + app.getRam(), vm.getCPU() + app.getCpu()); + break; + } catch (VMResizeException ex) { + vm = null; + } + } + if (vm == null) { + try { + vm = manager.startPhysicalMachine().startVirtualMachine(app.getSize(), app.getRam(), app.getCpu(), vmType); + } catch (OutOfPMsException e) { + // LOG.error("failed to start PM.", e); + if (federation.askToOutsource(app)) { + insertOutsourcedStartEvent(currTime + 1, app); + } else + LOG.info("delaying the start of:" + app); + return; + } + } + vm.startApplication(app); + app.setRunningOn(vm); + insertStopEvent(currTime + app.getDuration(), app); + } + delayedApps = newDelayedApps; } /** * Check if we can free up a VM to shut it down. */ - private void checkMigration() { + private void runMigration() { // TODO Auto-generated method stub } @@ -90,7 +155,7 @@ public class SchedulerB extends AbstractScheduler { vm.resizeVM(vm.getSize() - evt.getApp().getSize(), vm.getRAM() - evt.getApp().getRam(), vm.getCPU() - evt.getApp().getCpu()); } catch (VMResizeException e) { - LOG.error("failed to resize VM: " + e.getVm(), e); + // LOG.error("failed to resize VM: " + e.getVm(), e); } if (vm.getApplications().size() == 0) { PhysicalMachine pm = vm.getRunningOn(); @@ -114,7 +179,6 @@ public class SchedulerB extends AbstractScheduler { if (evt.getType() == EventType.startApplication) { VirtualMachine vm = null; for (PhysicalMachine pm : manager.getPMs()) { - LOG.debug("PMs: " + pm); vm = pm.getVirtualMachines().get((pm.getVirtualMachines().keySet().toArray(new Integer[0]))[0]); try { vm.resizeVM(vm.getSize() + evt.getApp().getSize(), vm.getRAM() + evt.getApp().getRam(), vm.getCPU() @@ -129,8 +193,10 @@ public class SchedulerB extends AbstractScheduler { vm = manager.startPhysicalMachine().startVirtualMachine(evt.getApp().getSize(), evt.getApp().getRam(), evt.getApp().getCpu(), vmType); } catch (OutOfPMsException e) { - LOG.error("failed to start PM.", e); - // TODO: try outsourcing here. + if (federation.askToOutsource(evt.getApp())) { + insertOutsourcedStartEvent(currTime + 1, evt.getApp()); + } else + LOG.info("delaying the start of:" + evt.getApp()); delayedApps.add(evt.getApp()); return; } diff --git a/src/at/ac/tuwien/lsdc/types/SchedulerEvent.java b/src/at/ac/tuwien/lsdc/types/SchedulerEvent.java index 6e96e3a..11f21ba 100644 --- a/src/at/ac/tuwien/lsdc/types/SchedulerEvent.java +++ b/src/at/ac/tuwien/lsdc/types/SchedulerEvent.java @@ -3,7 +3,7 @@ package at.ac.tuwien.lsdc.types; public class SchedulerEvent { public enum EventType { - startApplication, endApplication + startApplication, endApplication, startOutsourcedApplication, endOutsourcedApplication }; final private long timestamp; -- 2.43.0