Commit 00417e2e authored by Lucas Cavalcante's avatar Lucas Cavalcante
Browse files

fix to vertical scaling

parent a207c6af
......@@ -22,6 +22,7 @@ import org.cloudbus.cloudsim.provisioners.PeProvisionerSimple;
import org.cloudbus.cloudsim.provisioners.ResourceProvisioner;
import org.cloudbus.cloudsim.provisioners.ResourceProvisionerShared;
import org.cloudbus.cloudsim.provisioners.ResourceProvisionerSimple;
import org.cloudbus.cloudsim.resources.Iops;
import org.cloudbus.cloudsim.resources.Pe;
import org.cloudbus.cloudsim.resources.PeSimple;
import org.cloudbus.cloudsim.schedulers.cloudlet.CloudletSchedulerSpaceShared;
......@@ -37,6 +38,9 @@ import org.cloudbus.cloudsim.utilizationmodels.UtilizationModelFull;
import org.cloudbus.cloudsim.utilizationmodels.UtilizationModelUneven;
import org.cloudbus.cloudsim.vms.Vm;
import org.cloudbus.cloudsim.vms.VmSimple;
import org.cloudsimplus.autoscaling.VerticalVmScaling;
import org.cloudsimplus.autoscaling.VerticalVmScalingSimple;
import org.cloudsimplus.autoscaling.resources.ResourceScalingInstantaneous;
import org.cloudsimplus.builders.tables.CloudletsTableBuilder;
import org.cloudsimplus.slametrics.SlaContract;
import org.cloudsimplus.slametrics.SlaMetric;
......@@ -73,19 +77,22 @@ public class SlaExploitationSimulation {
public static int MIGRATION_TIME;
// HOST
private static final int HOST_PES = 160;
private static final int HOST_PES = 25;
public static final int HOST_MIPS = 1000;
public static final int HOST_RAM = 32 * 1024;
public static final int HOST_BW = 1024;
public static final int HOST_BASE_STORAGE = 10 * 1024 * 1024;
public static final int HOST_RAM = 25 * 1024;
public static final int HOST_BW = 1000000;
public static final int HOST_BASE_STORAGE = 2 * 1024 * 1024;
// VM AND CLOUDLET
private static final int NUM_INSTR = 1;
private static final int VM_PES = 1;
private static final int VM_MIPS = 500;
private static final int VM_BW = 10;
private static final int VM_RAM = 1;
private static final int VM_RAM = 1024;
private static final int VM_STORAGE = 100 * 1024;
private static final double UPPER_THRESHOLD = 0.8;
private static final double LOWER_THRESHOLD = 0.2;
public static final double IMPRECISION = 0.0001;
......@@ -101,15 +108,15 @@ public class SlaExploitationSimulation {
public static void main(String[] args) {
//PATH = args[0];
SLA_TIGHT_HOSTS = 0;
SLA_LOOSE_HOSTS = 1;
HOST_IOPS = 500;
SLA_LOOSE_HOSTS = 10;
HOST_IOPS = 2500;
MINIMUM_IOPS = 100;
LOW_AVAILABILITY = 99;
VMS = 1;
CLOUDLETS = 1;
CLOUDLET_IOPS = 1000;
LOW_AVAILABILITY = 99.9;
VMS = 250;
CLOUDLETS = 250;
VM_IOPS = 100;
MIGRATION_TIME = 10;
CLOUDLET_IOPS = 12 * 60 * 60 * VM_IOPS;
MIGRATION_TIME = 30;
random = new Random(1);
......@@ -126,6 +133,98 @@ public class SlaExploitationSimulation {
new SlaExploitationSimulation();
}
/**
* 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;
}
public SlaExploitationSimulation() {
this.simulation = new CloudSim(10);
......@@ -226,7 +325,7 @@ public class SlaExploitationSimulation {
final List<Vm> list = new ArrayList<Vm>(VMS);
for (int i = 0; i < VMS; i++) {
Vm vm = new VmSimple(i, VM_MIPS, VM_PES).setRam(VM_RAM).setBw(VM_BW).setSize(VM_STORAGE)
.setIops(VM_IOPS).setCloudletScheduler(new CloudletSchedulerTimeShared());
.setIops(VM_IOPS).setCloudletScheduler(new CloudletSchedulerSpaceShared());
vm.setContract(contract);
list.add(vm);
}
......
......@@ -44,9 +44,11 @@ public class VmAllocationPolicyMigrationSla extends VmAllocationPolicyAbstract {
private static final String TIGHT = "TIGHT";
private static final Double IMPRECISION = 0.001;
private final int MIGRATION_TIME;
private static final double UPPER_THRESHOLD = 0.8;
private static final double LOWER_THRESHOLD = 0.2;
private VerticalVmScaling iopsScaling;
private final int MIGRATION_TIME;
private VmAllocationPolicy allocationPolicy;
......@@ -65,15 +67,6 @@ public class VmAllocationPolicyMigrationSla extends VmAllocationPolicyAbstract {
this.MIGRATION_TIME = migrationTime;
this.previousFragmentation = new HashMap<Host, Double>();
this.currentFragmentation = new HashMap<Host, Double>();
this.iopsScaling = null;
}
public VmAllocationPolicyMigrationSla(VmAllocationPolicy allocationPolicy, int migrationTime, VerticalVmScaling iopsScaling) {
this.allocationPolicy = allocationPolicy;
this.MIGRATION_TIME = migrationTime;
this.previousFragmentation = new HashMap<Host, Double>();
this.currentFragmentation = new HashMap<Host, Double>();
this.iopsScaling = iopsScaling;
}
@Override
......@@ -108,6 +101,7 @@ public class VmAllocationPolicyMigrationSla extends VmAllocationPolicyAbstract {
}
Map<Vm, Host> migrationMap = new HashMap<Vm, Host>();
VerticalVmScaling iopsScaling;
//for each hell host
for(Host h : tightSlaHosts){
......@@ -123,7 +117,10 @@ public class VmAllocationPolicyMigrationSla extends VmAllocationPolicyAbstract {
if(h.isSuitableForVm(vm) && h.addMigratingInVm(vm)){
migrationMap.put(vm, h);
vmIterator.remove();
iopsScaling = createVerticalIopsScaling();
vm.setIopsVerticalScaling(iopsScaling);
iopsScaling.setVm(vm);
}
}
}
......@@ -145,7 +142,9 @@ public class VmAllocationPolicyMigrationSla extends VmAllocationPolicyAbstract {
if(h.isSuitableForVm(vm) && h.addMigratingInVm(vm)){
migrationMap.put(vm, h);
vmIterator.remove();
vm.setIopsVerticalScaling(VerticalVmScaling.NULL);
iopsScaling = VerticalVmScaling.NULL;
vm.setIopsVerticalScaling(iopsScaling);
iopsScaling.setVm(vm);
}
}
}
......@@ -155,6 +154,98 @@ public class VmAllocationPolicyMigrationSla extends VmAllocationPolicyAbstract {
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,
* or a list of hosts from low to high fragmentation
......@@ -248,8 +339,7 @@ public class VmAllocationPolicyMigrationSla extends VmAllocationPolicyAbstract {
for (Host h : tightSlaHosts) {
for (Vm vm : h.getVmList()) {
if (vm.getMonitor().getCumulativeVmViolationTime(clock) + MIGRATION_TIME >=
vm.getMonitor().getMaximumAllowedSlaViolationTime()) {
if (vm.getMonitor().getCumulativeCredit(clock) - MIGRATION_TIME >= 0) {
vmList.add(vm);
}
}
......
......@@ -208,7 +208,12 @@ public class CloudSim implements Simulation {
this.alreadyRunOnce = true;
while (running) {
int count = 0;
runClockTickAndProcessFutureEventQueue();
if(clock % 3600 <= 10) {
count++;
printMessage(count + "hr passed " + clock);
}
if(abortRequested){
printMessage("\n================== Simulation aborted under request at time "+ clock +" ==================");
return clock;
......
......@@ -135,10 +135,6 @@ public class CsvGenerator {
writer.append(',');
writer.append("cloudlet-id");
writer.append(',');
writer.append("current-sla-violation");
writer.append(',');
writer.append("cumulative-sla-violation");
writer.append(',');
writer.append("vm-credit");
writer.append(',');
writer.append('\n');
......@@ -158,10 +154,6 @@ public class CsvGenerator {
writer.append(String.valueOf(i));
writer.append(',');
writer.append(String.valueOf(cl.getId()));
writer.append(',');
writer.append(String.valueOf(cl.getVm().getMonitor().getInstantaneousVmViolationTime(i)));
writer.append(',');
writer.append(String.valueOf(cl.getVm().getMonitor().getCumulativeVmViolationTime(i)));
writer.append(',');
writer.append(String.valueOf(cl.getVm().getMonitor().getCumulativeCredit(i)));
writer.append('\n');
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment