]> git.somenet.org - pub/jan/lsdc.git/blob - src/at/ac/tuwien/lsdc/sched/SchedulerB.java
added Migration to SchedB
[pub/jan/lsdc.git] / src / at / ac / tuwien / lsdc / sched / SchedulerB.java
1 package at.ac.tuwien.lsdc.sched;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.util.Collections;
6 import java.util.LinkedList;
7 import java.util.List;
8
9 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory;
11
12 import at.ac.tuwien.lsdc.exception.OutOfPMsException;
13 import at.ac.tuwien.lsdc.exception.VMResizeException;
14 import at.ac.tuwien.lsdc.types.Application;
15 import at.ac.tuwien.lsdc.types.PhysicalMachine;
16 import at.ac.tuwien.lsdc.types.ScenarioType;
17 import at.ac.tuwien.lsdc.types.SchedulerEvent;
18 import at.ac.tuwien.lsdc.types.SchedulerType;
19 import at.ac.tuwien.lsdc.types.VirtualMachine;
20 import at.ac.tuwien.lsdc.types.VirtualMachine.VMType;
21
22 /**
23  * Scheduler B.
24  *
25  * Initial State: All PMs switched off. If an application arrives, try to modify size, CPU and RAM
26  * of an existing VM to run the application. If no VM is running, create a new one (start a new PM
27  * if necessary). If the application has finished decrease the size, CPU and RAM of the VM. If no
28  * applications are running on a VM, shut down the VM. If no VM is running on a PM, shut down the
29  * PM. Try to get a maximum of utilization on every PM. Migration: Try to move applications from VMs
30  * to other VMs to get a better utilization and to use less PMs.
31  *
32  * @author jan
33  *
34  */
35 public class SchedulerB extends AbstractScheduler {
36         /**
37          * Logger.
38          */
39         private static final Logger LOG = LoggerFactory.getLogger(SchedulerB.class);
40
41         public SchedulerB(int numPMs, int numCloudPartners, File schedulerLog, ScenarioType scenario)
42                         throws IOException {
43                 super(numPMs, numCloudPartners, schedulerLog, scenario);
44                 vmType = VMType.Resizable;
45         }
46
47         /**
48          * Check if we can free up a VM to shut it down.
49          */
50         @Override
51         protected void runMigration() {
52                 List<PhysicalMachine> pms = manager.getSortedPMs();
53                 // iterate through all the PMs (except the one with the highest utilization)
54                 for (int i = 0; i < (pms.size() - 1); i++) {
55                         PhysicalMachine currentPM = pms.get(i);
56                         if (currentPM.isRunning() && (currentPM.getTotalVMs() > 0)) {
57                                 VirtualMachine currentVM = currentPM.getVirtualMachines().values().iterator()
58                                                 .next();
59                                 for (Application app : currentVM.getApplications()) {
60                                         for (int j = i; i < pms.size(); i++) {
61                                                 PhysicalMachine nextPM = pms.get(j);
62                                                 if (nextPM.isRunning() && (nextPM.getTotalVMs() > 0)) {
63                                                         VirtualMachine nextVM = nextPM.getVirtualMachines().values().iterator()
64                                                                         .next();
65                                                         if (deployApp(nextVM, app)) {
66                                                                 currentVM.stopApplication(app);
67                                                                 break;
68                                                         }
69                                                 }
70                                         }
71                                 }
72                                 if (currentVM.getApplications().size() == 0) {
73                                         currentPM.stopVirtualMachine(currentVM);
74                                         if (currentPM.getTotalVMs() == 0) {
75                                                 manager.stopPhysicalMachine(currentPM.getId());
76                                         }
77                                 }
78                         }
79                 }
80         }
81
82         private boolean deployApp(VirtualMachine vm, Application app) {
83                 if (!vm.enoughResources(app)) {
84                         try {
85                                 vm.resizeVM(vm.getSize() + app.getSize(), vm.getRAM() + app.getRam(), vm.getCPU()
86                                                 + app.getCpu());
87                         } catch (VMResizeException ex) {
88                                 return false;
89                         }
90                 }
91                 vm.startApplication(app);
92                 app.setRunningOn(vm);
93                 return true;
94         }
95
96         /**
97          * Cleanup completed apps. Downsize VMs and if an VM becomes empty, shut down VM + PM.
98          *
99          * @param events list of all events that happened in this timeslot.
100          */
101         @Override
102         protected void handleEndEvents(LinkedList<SchedulerEvent> events) {
103                 LOG.debug("stopApps():" + events);
104                 for (SchedulerEvent evt : events) {
105                         VirtualMachine vm = evt.getApp().getRunningOn();
106                         evt.getApp().setRunningOn(null);
107                         vm.stopApplication(evt.getApp());
108                         try {
109                                 vm.resizeVM(vm.getSize() - evt.getApp().getSize(), vm.getRAM()
110                                                 - evt.getApp().getRam(), vm.getCPU() - evt.getApp().getCpu());
111                         } catch (VMResizeException e) {
112                                 // LOG.error("failed to resize VM: " + e.getVm(), e);
113                         }
114                         if (vm.getApplications().size() == 0) {
115                                 PhysicalMachine pm = vm.getRunningOn();
116                                 pm.stopVirtualMachine(vm);
117                                 manager.stopPhysicalMachine(pm.getId());
118                         }
119                 }
120         }
121
122         /**
123          * Try to start all Apps. Upsize the VM, if not possible start another PM, if not possible,
124          * delay start.
125          *
126          * @param events list of all events that happened in this timeslot.
127          */
128         @Override
129         protected void handleStartEvents(LinkedList<SchedulerEvent> events) {
130                 LOG.debug("startApps():" + events);
131                 boolean deployed = false;
132                 for (SchedulerEvent evt : events) {
133                         VirtualMachine vm = null;
134                         List<PhysicalMachine> sortedPMs = manager.getSortedPMs();
135                         Collections.reverse(sortedPMs);
136                         for (PhysicalMachine pm : sortedPMs) {
137                                 if (pm.isRunning() && (pm.getTotalVMs() > 0)) {
138                                         vm = pm.getVirtualMachines().values().iterator().next();
139                                         deployed = deployApp(vm, evt.getApp());
140                                         if (deployed)
141                                                 break;
142                                 }
143                         }
144                         if (vm == null) {
145                                 try {
146                                         vm = manager.startPhysicalMachine().startVirtualMachine(evt.getApp().getSize(),
147                                                         evt.getApp().getRam(), evt.getApp().getCpu(), vmType);
148                                         deployed = deployApp(vm, evt.getApp());
149                                 } catch (OutOfPMsException e) {
150                                         if (federation.askToOutsource(evt.getApp())) {
151                                                 insertOutsourcedStartEvent(currTime + 1, evt.getApp());
152                                         } else
153                                                 LOG.info("delaying the start of:" + evt.getApp());
154                                         delayedApps.add(evt.getApp());
155                                         return;
156                                 }
157                         }
158                         if (deployed)
159                                 insertStopEvent(currTime + evt.getApp().getDuration(), evt.getApp());
160                 }
161         }
162
163         @Override
164         protected String getSchedulerType() {
165                 return SchedulerType.B.toString();
166         }
167
168 }