Commit 4fd3fdf9 authored by Eduardo Falcão's avatar Eduardo Falcão
Browse files

fixing the change of host heaven into hell

parent 42b0c8f9
...@@ -77,12 +77,12 @@ public class SlaExploitationSimulation { ...@@ -77,12 +77,12 @@ public class SlaExploitationSimulation {
private static int VM_IOPS; private static int VM_IOPS;
public static int MIGRATION_TIME; public static int MIGRATION_TIME;
public static final int SCHEDULING_TIME = 10; public static final int SCHEDULING_TIME = 1;
private static final int MAX_VMS_ON_TIGHT_HOST = 50; private static final int MAX_VMS_ON_TIGHT_HOST = 2;
// HOST // HOST
private static final int HOST_PES = 25; private static final int HOST_PES = 1;
public static final int HOST_MIPS = 1000; public static final int HOST_MIPS = 1000;
public static final int HOST_RAM = MAX_VMS_ON_TIGHT_HOST * 1024; public static final int HOST_RAM = MAX_VMS_ON_TIGHT_HOST * 1024;
public static final int HOST_BW = 1000000; public static final int HOST_BW = 1000000;
...@@ -110,16 +110,19 @@ public class SlaExploitationSimulation { ...@@ -110,16 +110,19 @@ public class SlaExploitationSimulation {
public static void main(String[] args) { public static void main(String[] args) {
//PATH = args[0]; //PATH = args[0];
SLA_TIGHT_HOSTS = 0; SLA_TIGHT_HOSTS = 0;
SLA_LOOSE_HOSTS = 10; SLA_LOOSE_HOSTS = 2;
HOST_IOPS = MAX_VMS_ON_TIGHT_HOST * 100;
MINIMUM_IOPS = 101;
LOW_AVAILABILITY = 99;
VMS = 250;
CLOUDLETS = VMS;
VM_IOPS = 100; VM_IOPS = 100;
CLOUDLET_IOPS = 2 * 60 * 60 * VM_IOPS; HOST_IOPS = VM_IOPS;
MIGRATION_TIME = 5; LOW_AVAILABILITY = 99;
VMS = 2;
CLOUDLETS = VMS;
CLOUDLET_IOPS = 3 * 60 * 60 * VM_IOPS;
MIGRATION_TIME = 10;
random = new Random(1); random = new Random(1);
//1000 migra pro inferno
//1001 migra de volta pro céu
FILEID = "tight"+SLA_TIGHT_HOSTS+"-"+ FILEID = "tight"+SLA_TIGHT_HOSTS+"-"+
...@@ -203,7 +206,7 @@ public class SlaExploitationSimulation { ...@@ -203,7 +206,7 @@ public class SlaExploitationSimulation {
hosts.add(host); hosts.add(host);
} }
final Datacenter dc = new DatacenterSimple(simulation, hosts, vmAllocationpolicy); final Datacenter dc = new DatacenterSimple(simulation, hosts, vmAllocationpolicy, MIGRATION_TIME);
return dc; return dc;
} }
...@@ -256,7 +259,7 @@ public class SlaExploitationSimulation { ...@@ -256,7 +259,7 @@ public class SlaExploitationSimulation {
for (int i = 0; i < CLOUDLETS; i++) { for (int i = 0; i < CLOUDLETS; i++) {
Cloudlet cloudlet = new CloudletSimple(i, NUM_INSTR, VM_PES).setFileSize(1000) Cloudlet cloudlet = new CloudletSimple(i, NUM_INSTR, VM_PES).setFileSize(1000)
.setOutputSize(1000).setUtilizationModel(utilization) .setOutputSize(1000).setUtilizationModel(utilization)
.setUtilizationModelIops(new UtilizationModelAbsolute(99)) .setUtilizationModelIops(new UtilizationModelAbsolute(100))
.setIops(CLOUDLET_IOPS); .setIops(CLOUDLET_IOPS);
list.add(cloudlet); list.add(cloudlet);
......
...@@ -157,97 +157,7 @@ public class VmAllocationPolicyMigrationSla extends VmAllocationPolicyAbstract { ...@@ -157,97 +157,7 @@ public class VmAllocationPolicyMigrationSla extends VmAllocationPolicyAbstract {
return migrationMap; return migrationMap;
} }
/**
* Creates a {@link VerticalVmScaling} for scaling VM's IOPS when it's under or
* overloaded.
*
* <p>
* Realize the lower and upper thresholds are defined inside this method by
* using references to the methods {@link #lowerIopsUtilizationThreshold(Vm)}
* and {@link #upperIopsUtilizationThreshold(Vm)}. These methods enable defining
* thresholds in a dynamic way and even different thresholds for distinct VMs.
* Therefore, it's a powerful mechanism.
* </p>
*
* <p>
* However, if you are defining thresholds in a static way, and they are the
* same for all VMs, you can use a Lambda Expression like below, for instance,
* instead of creating a new method that just returns a constant value:<br>
* {@code verticalIopsScaling.setLowerThresholdFunction(vm -> 0.4);}
* </p>
*
* @see #createListOfScalableVms(int)
*/
private VerticalVmScaling createVerticalIopsScaling() {
// The percentage in which the amount of IOPS has to be scaled
final double scalingFactor = 0.25;
VerticalVmScalingSimple verticalIopsScaling = new VerticalVmScalingSimple(Iops.class, scalingFactor);
/*
* Instead of gradually increasing or decreasing the amount of IOPS, when the
* scaling object detects the Disk usage is above or below the defined
* thresholds, it will automatically calculate the amount of IOPS to add/remove
* to move the VM from the over or underload condition.
*/
verticalIopsScaling.setResourceScaling(new ResourceScalingInstantaneous());
/**
* Different from the line above, the line below implements a ResourceScaling
* using a Lambda Expression. It is just an example which scales the resource
* twice the amount defined by the scaling factor defined in the constructor.
*
* Realize that if the setResourceScaling method is not called, a
* ResourceScalingGradual will be used, which scales the resource according to
* the scaling factor. The lower and upper thresholds after this line can also
* be defined using a Lambda Expression.
*
* So, here we are defining our own {@link ResourceScaling} instead of using the
* available ones such as the {@link ResourceScalingGradual} or
* {@link ResourceScalingInstantaneous}.
*/
// verticalIopsScaling.setResourceScaling(vs ->
// 2*vs.getScalingFactor()*vs.getAllocatedResource());
verticalIopsScaling.setLowerThresholdFunction(this::lowerIopsUtilizationThreshold);
verticalIopsScaling.setUpperThresholdFunction(this::upperIopsUtilizationThreshold);
return verticalIopsScaling;
}
/**
* Defines the minimum Disk utilization percentage that indicates a Vm is
* underloaded. This function is using a statically defined threshold, but it
* would be defined a dynamic threshold based on any condition you want. A
* reference to this method is assigned to each Vertical VM Scaling created.
*
* @param vm
* the VM to check if its Disk is underloaded. <b>The parameter is
* not being used internally, which means the same threshold is used
* for any Vm.</b>
* @return the lower Disk utilization threshold
* @see #createVerticalIopsScaling()
*/
private double lowerIopsUtilizationThreshold(Vm vm) {
return LOWER_THRESHOLD;
}
/**
* Defines the maximum Disk utilization percentage that indicates a Vm is
* overloaded. This function is using a statically defined threshold, but it
* would be defined a dynamic threshold based on any condition you want. A
* reference to this method is assigned to each Vertical VM Scaling created.
*
* @param vm
* the VM to check if its Disk is overloaded. The parameter is not
* being used internally, that means the same threshold is used for
* any Vm.
* @return the upper Disk utilization threshold
* @see #createVerticalIopsScaling()
*/
private double upperIopsUtilizationThreshold(Vm vm) {
return UPPER_THRESHOLD;
}
/** /**
* Sorts a list of VMs from high to low fragmentation, * Sorts a list of VMs from high to low fragmentation,
...@@ -310,11 +220,14 @@ public class VmAllocationPolicyMigrationSla extends VmAllocationPolicyAbstract { ...@@ -310,11 +220,14 @@ public class VmAllocationPolicyMigrationSla extends VmAllocationPolicyAbstract {
for (Host h : looseSlaHosts) { for (Host h : looseSlaHosts) {
for (Vm vm : h.getVmList()) { for (Vm vm : h.getVmList()) {
System.out.println("#$#Heaven#$# vm id("+vm.getId()+"): "+vm.getMonitor().getCumulativeCredit(clock));
// TODO (IF) Create method with code bellow // TODO (IF) Create method with code bellow
if(vm.isInMigration() && !isLooseHost(vm.gethostInMigration())){ if(vm.isInMigration() && !isLooseHost(vm.gethostInMigration())){
continue; continue;
} }
if (vm.getMonitor().getCumulativeCredit(clock) - MIGRATION_TIME >= 0) { if (vm.getMonitor().getCumulativeCredit(clock) - MIGRATION_TIME >= 0) {
candidateVmsToMigrate.add(vm); candidateVmsToMigrate.add(vm);
} }
} }
...@@ -346,6 +259,7 @@ public class VmAllocationPolicyMigrationSla extends VmAllocationPolicyAbstract { ...@@ -346,6 +259,7 @@ public class VmAllocationPolicyMigrationSla extends VmAllocationPolicyAbstract {
for (Host h : tightSlaHosts) { for (Host h : tightSlaHosts) {
for (Vm vm : h.getVmList()) { for (Vm vm : h.getVmList()) {
System.out.println("#$#Hell#$# vm id("+vm.getId()+"): "+vm.getMonitor().getCumulativeCredit(clock));
if (vm.getMonitor().getCumulativeCredit(clock) <= MIGRATION_TIME + SCHEDULING_TIME) { if (vm.getMonitor().getCumulativeCredit(clock) <= MIGRATION_TIME + SCHEDULING_TIME) {
vmList.add(vm); vmList.add(vm);
} }
...@@ -401,9 +315,100 @@ public class VmAllocationPolicyMigrationSla extends VmAllocationPolicyAbstract { ...@@ -401,9 +315,100 @@ public class VmAllocationPolicyMigrationSla extends VmAllocationPolicyAbstract {
return allocationPolicy.findHostForVm(vm); return allocationPolicy.findHostForVm(vm);
} }
//TODO Rename method name public int getMigrationTime() {
public int getMIGRATION_TIME() {
return MIGRATION_TIME; return MIGRATION_TIME;
} }
/**
* Creates a {@link VerticalVmScaling} for scaling VM's IOPS when it's under or
* overloaded.
*
* <p>
* Realize the lower and upper thresholds are defined inside this method by
* using references to the methods {@link #lowerIopsUtilizationThreshold(Vm)}
* and {@link #upperIopsUtilizationThreshold(Vm)}. These methods enable defining
* thresholds in a dynamic way and even different thresholds for distinct VMs.
* Therefore, it's a powerful mechanism.
* </p>
*
* <p>
* However, if you are defining thresholds in a static way, and they are the
* same for all VMs, you can use a Lambda Expression like below, for instance,
* instead of creating a new method that just returns a constant value:<br>
* {@code verticalIopsScaling.setLowerThresholdFunction(vm -> 0.4);}
* </p>
*
* @see #createListOfScalableVms(int)
*/
private VerticalVmScaling createVerticalIopsScaling() {
// The percentage in which the amount of IOPS has to be scaled
final double scalingFactor = 0.25;
VerticalVmScalingSimple verticalIopsScaling = new VerticalVmScalingSimple(Iops.class, scalingFactor);
/*
* Instead of gradually increasing or decreasing the amount of IOPS, when the
* scaling object detects the Disk usage is above or below the defined
* thresholds, it will automatically calculate the amount of IOPS to add/remove
* to move the VM from the over or underload condition.
*/
verticalIopsScaling.setResourceScaling(new ResourceScalingInstantaneous());
/**
* Different from the line above, the line below implements a ResourceScaling
* using a Lambda Expression. It is just an example which scales the resource
* twice the amount defined by the scaling factor defined in the constructor.
*
* Realize that if the setResourceScaling method is not called, a
* ResourceScalingGradual will be used, which scales the resource according to
* the scaling factor. The lower and upper thresholds after this line can also
* be defined using a Lambda Expression.
*
* So, here we are defining our own {@link ResourceScaling} instead of using the
* available ones such as the {@link ResourceScalingGradual} or
* {@link ResourceScalingInstantaneous}.
*/
// verticalIopsScaling.setResourceScaling(vs ->
// 2*vs.getScalingFactor()*vs.getAllocatedResource());
verticalIopsScaling.setLowerThresholdFunction(this::lowerIopsUtilizationThreshold);
verticalIopsScaling.setUpperThresholdFunction(this::upperIopsUtilizationThreshold);
return verticalIopsScaling;
}
/**
* Defines the minimum Disk utilization percentage that indicates a Vm is
* underloaded. This function is using a statically defined threshold, but it
* would be defined a dynamic threshold based on any condition you want. A
* reference to this method is assigned to each Vertical VM Scaling created.
*
* @param vm
* the VM to check if its Disk is underloaded. <b>The parameter is
* not being used internally, which means the same threshold is used
* for any Vm.</b>
* @return the lower Disk utilization threshold
* @see #createVerticalIopsScaling()
*/
private double lowerIopsUtilizationThreshold(Vm vm) {
return LOWER_THRESHOLD;
}
/**
* Defines the maximum Disk utilization percentage that indicates a Vm is
* overloaded. This function is using a statically defined threshold, but it
* would be defined a dynamic threshold based on any condition you want. A
* reference to this method is assigned to each Vertical VM Scaling created.
*
* @param vm
* the VM to check if its Disk is overloaded. The parameter is not
* being used internally, that means the same threshold is used for
* any Vm.
* @return the upper Disk utilization threshold
* @see #createVerticalIopsScaling()
*/
private double upperIopsUtilizationThreshold(Vm vm) {
return UPPER_THRESHOLD;
}
} }
...@@ -49,21 +49,19 @@ public class VmAllocationPolicyMigrationSlaDynamicTightHost extends VmAllocation ...@@ -49,21 +49,19 @@ public class VmAllocationPolicyMigrationSlaDynamicTightHost extends VmAllocation
int numberCreditVms = getVmsWithEnoughCredit(getHostsWithLooseSla()).size(); int numberCreditVms = getVmsWithEnoughCredit(getHostsWithLooseSla()).size();
System.out.println("Vms with credit: "+numberCreditVms); System.out.println("Vms with credit in Heaven: "+numberCreditVms);
// Check if the number of vms with credit also consider the vms with credit that are // Check if the number of vms with credit also consider the vms with credit that are
// in the Tight hosts (Check vms that are current migrating) // in the Tight hosts (Check vms that are current migrating)
if(numberCreditVms >= getVmsThreshold() && currentTightHosts < getLimitTightHosts()) { if(numberCreditVms >= getVmsThreshold() && currentTightHosts < getLimitTightHosts()) {
System.out.println("INFERNO!!"); System.out.println("INFERNO!! "+getDatacenter().getSimulation().clock());
System.out.println("INFERNO!!");
System.out.println("INFERNO!!");
System.out.println("INFERNO!!");
// The Tight host can be created // The Tight host can be created
// Select the Loose host with more credit Vms // Select the Loose host with more credit Vms
Host bestCandidateHost = getTightHostCandidate(); Host bestCandidateHost = getTightHostCandidate();
// Make it a Tight host // Make it a Tight host
bestCandidateHost.setIopsProvisioner(new ResourceProvisionerShared()); bestCandidateHost.setIopsProvisioner(new ResourceProvisionerShared());
reprovisionIopsForVmsInHell(bestCandidateHost);
// bestCandidateHost.setVmScheduler(new VmSchedulerTimeShared()); // bestCandidateHost.setVmScheduler(new VmSchedulerTimeShared());
// Increase the number of Tight hosts // Increase the number of Tight hosts
currentTightHosts++; currentTightHosts++;
...@@ -104,7 +102,7 @@ public class VmAllocationPolicyMigrationSlaDynamicTightHost extends VmAllocation ...@@ -104,7 +102,7 @@ public class VmAllocationPolicyMigrationSlaDynamicTightHost extends VmAllocation
// Check how good candidate this host is // Check how good candidate this host is
int creditVms = 0; int creditVms = 0;
for (Vm vm : host.getVmList()) { for (Vm vm : host.getVmList()) {
if (vm.getMonitor().getCumulativeCredit(clock) - getMIGRATION_TIME() >= 0) { if (vm.getMonitor().getCumulativeCredit(clock) - getMigrationTime() >= 0) {
creditVms++; creditVms++;
} }
} }
...@@ -114,7 +112,7 @@ public class VmAllocationPolicyMigrationSlaDynamicTightHost extends VmAllocation ...@@ -114,7 +112,7 @@ public class VmAllocationPolicyMigrationSlaDynamicTightHost extends VmAllocation
} }
} }
System.out.println(bestCandidateHost); System.out.println("bestCandidateHost: "+bestCandidateHost);
return bestCandidateHost; return bestCandidateHost;
} }
...@@ -146,6 +144,12 @@ public class VmAllocationPolicyMigrationSlaDynamicTightHost extends VmAllocation ...@@ -146,6 +144,12 @@ public class VmAllocationPolicyMigrationSlaDynamicTightHost extends VmAllocation
return looseHosts; return looseHosts;
} }
private void reprovisionIopsForVmsInHell(Host hellHost){
for(Vm vm : hellHost.getVmList()){
hellHost.getIopsProvisioner().allocateResourceForVm(vm, vm.getCurrentRequestedIops());
}
}
private int getVmsThreshold() { private int getVmsThreshold() {
return vmsThreshold; return vmsThreshold;
} }
......
...@@ -70,6 +70,44 @@ public class DatacenterSimple extends CloudSimEntity implements Datacenter { ...@@ -70,6 +70,44 @@ public class DatacenterSimple extends CloudSimEntity implements Datacenter {
/** @see #getSchedulingInterval() */ /** @see #getSchedulingInterval() */
private double schedulingInterval; private double schedulingInterval;
private int migrationTime;
/**
* Creates a Datacenter.
*
* @param simulation The CloudSim instance that represents the simulation the Entity is related to
* @param hostList list of {@link Host}s that will compound the Datacenter
* @param vmAllocationPolicy the policy to be used to allocate VMs into hosts
* @param migrationTime the duration of the migration
* @throws IllegalArgumentException when this entity has <tt>zero</tt> number of PEs (Processing Elements).
* <br>
* No PEs mean the Cloudlets can't be processed. A CloudResource must
* contain one or more Machines. A Machine must contain one or more PEs.
*
* @post $none
*/
public DatacenterSimple(
final Simulation simulation,
final List<? extends Host> hostList,
final VmAllocationPolicy vmAllocationPolicy,
final int migrationTime)
{
super(simulation);
setHostList(hostList);
setLastProcessTime(0.0);
setSchedulingInterval(0);
setStorageList(new ArrayList<>());
this.characteristics = new DatacenterCharacteristicsSimple(this);
this.bandwidthPercentForMigration = DEF_BANDWIDTH_PERCENT_FOR_MIGRATION;
migrationsEnabled = true;
setVmAllocationPolicy(vmAllocationPolicy);
this.migrationTime = migrationTime;
}
/** /**
* Creates a Datacenter. * Creates a Datacenter.
...@@ -712,7 +750,10 @@ public class DatacenterSimple extends CloudSimEntity implements Datacenter { ...@@ -712,7 +750,10 @@ public class DatacenterSimple extends CloudSimEntity implements Datacenter {
final Host sourceHost = entry.getKey().getHost(); final Host sourceHost = entry.getKey().getHost();
final Host targetHost = entry.getValue(); final Host targetHost = entry.getValue();
final double delay = timeToMigrateVm(entry.getKey(), targetHost); //FIXME this was done in the context of the autonomics project
// final double delay = timeToMigrateVm(entry.getKey(), targetHost);
final double delay = migrationTime;
if (sourceHost == Host.NULL) { if (sourceHost == Host.NULL) {
Log.printFormattedLine( Log.printFormattedLine(
"%.2f: Migration of %s to %s is started.", "%.2f: Migration of %s to %s is started.",
...@@ -722,9 +763,13 @@ public class DatacenterSimple extends CloudSimEntity implements Datacenter { ...@@ -722,9 +763,13 @@ public class DatacenterSimple extends CloudSimEntity implements Datacenter {
"%.2f: Migration of %s from %s to %s is started.", "%.2f: Migration of %s from %s to %s is started.",
currentTime, entry.getKey(), sourceHost, targetHost); currentTime, entry.getKey(), sourceHost, targetHost);
} }
// Log.printFormattedLine(
// "\tIt's expected to finish in %.2f seconds, considering the %.0f%% of bandwidth allowed for migration and the VM RAM size.",
// delay, getBandwidthPercentForMigration()*100);
Log.printFormattedLine( Log.printFormattedLine(
"\tIt's expected to finish in %.2f seconds, considering the %.0f%% of bandwidth allowed for migration and the VM RAM size.", "\tIt's expected to finish in %.2f seconds. This is a fixed time in the context of the Autonomics project.",
delay, getBandwidthPercentForMigration()*100); delay, getBandwidthPercentForMigration()*100);
sourceHost.addVmMigratingOut(entry.getKey()); sourceHost.addVmMigratingOut(entry.getKey());
......
...@@ -83,12 +83,12 @@ public double getCumulativeCredit(double time) { ...@@ -83,12 +83,12 @@ public double getCumulativeCredit(double time) {
if((int) stateList.get(lastElement - 1).getTime() < (int) time) { if((int) stateList.get(lastElement - 1).getTime() < (int) time) {
VmStateHistoryEntry last = stateList.get(lastElement - 1); VmStateHistoryEntry last = stateList.get(lastElement - 1);
double utilization = utilizationList.get(lastUtilization - 1); double utilization = utilizationList.get(lastUtilization - 1);
Double previous = credits.get((int) last.getTime()); Double previous = credits.get((int) last.getTime());
if (last.getAllocatedIops() <= utilization) { if (last.getAllocatedIops() < utilization) {
cumulativeCredit = previous - (((int) time - stateList.get(lastElement - 1).getTime())) * (1 / availability); cumulativeCredit = previous - (((int) (time - stateList.get(lastElement - 1).getTime()))) * (1 / availability);
} else { } else {
cumulativeCredit = previous + (((int) time - stateList.get(lastElement - 1).getTime())) * (1 / availability); cumulativeCredit = previous + (((int) (time - stateList.get(lastElement - 1).getTime()))) * (1 / availability);
} }
} }
return cumulativeCredit; return cumulativeCredit;
...@@ -96,7 +96,7 @@ public double getCumulativeCredit(double time) { ...@@ -96,7 +96,7 @@ public double getCumulativeCredit(double time) {
private Double putCredits(VmStateHistoryEntry state, double utilization, double dif, double availability) { private Double putCredits(VmStateHistoryEntry state, double utilization, double dif, double availability) {
Double cumulativeCredit; Double cumulativeCredit;
if(state.getAllocatedIops() <= utilization) { if(state.getAllocatedIops() < utilization) {
credits.put((int) state.getTime(), dif - (1 / availability)); credits.put((int) state.getTime(), dif - (1 / availability));
} }
else { else {
...@@ -128,7 +128,7 @@ public double getCumulativeCredit(double time) { ...@@ -128,7 +128,7 @@ public double getCumulativeCredit(double time) {
return previous; return previous;
} }
if(state.getAllocatedIops() > utilization) if(state.getAllocatedIops() >= utilization)
dif = previous + (1 / availability) * (int )(time - prevTime - 1); dif = previous + (1 / availability) * (int )(time - prevTime - 1);
else else
dif = previous - (1 / availability) * (int )(time - prevTime - 1); dif = previous - (1 / availability) * (int )(time - prevTime - 1);
......
...@@ -182,7 +182,7 @@ public class VmAllocationPolicyMigrationSlaTest { ...@@ -182,7 +182,7 @@ public class VmAllocationPolicyMigrationSlaTest {
vm0.addStateHistoryEntry(new VmStateHistoryEntry(0, 0, 0, MINIMUM_IOPS - 1, 0, false)); // allocatedIops is MINIMUM_IOPS vm0.addStateHistoryEntry(new VmStateHistoryEntry(0, 0, 0, MINIMUM_IOPS - 1, 0, false)); // allocatedIops is MINIMUM_IOPS
vm0.setIOPSUtilization(0, MINIMUM_IOPS -1); vm0.setIOPSUtilization(0, MINIMUM_IOPS -1);
vm0.addStateHistoryEntry(