Commit bbe1814b authored by Rafael Vieira Falcão's avatar Rafael Vieira Falcão
Browse files

Merge branch 'sla-simulation' of...

Merge branch 'sla-simulation' of https://git.lsd.ufcg.edu.br/lenovo-autonomic/cloudsimplus into sla-simulation
parents 8c70761d c47e091b
package org.cloudbus.cloudsim.examples.autonomic;
import org.cloudbus.cloudsim.allocationpolicies.VmAllocationPolicySimple;
import org.cloudbus.cloudsim.brokers.DatacenterBroker;
import org.cloudbus.cloudsim.brokers.DatacenterBrokerSimple;
import org.cloudbus.cloudsim.cloudlets.Cloudlet;
import org.cloudbus.cloudsim.cloudlets.CloudletSimple;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.core.Simulation;
import org.cloudbus.cloudsim.datacenters.Datacenter;
import org.cloudbus.cloudsim.datacenters.DatacenterSimple;
import org.cloudbus.cloudsim.hosts.Host;
import org.cloudbus.cloudsim.hosts.HostSimple;
import org.cloudbus.cloudsim.provisioners.PeProvisionerSimple;
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.resources.Processor;
import org.cloudbus.cloudsim.schedulers.cloudlet.CloudletSchedulerTimeShared;
import org.cloudbus.cloudsim.schedulers.vm.VmSchedulerSpaceShared;
import org.cloudbus.cloudsim.schedulers.vm.VmSchedulerTimeShared;
import org.cloudbus.cloudsim.util.Log;
import org.cloudbus.cloudsim.utilizationmodels.UtilizationModel;
import org.cloudbus.cloudsim.utilizationmodels.UtilizationModelDynamic;
import org.cloudbus.cloudsim.utilizationmodels.UtilizationModelFull;
import org.cloudbus.cloudsim.utilizationmodels.UtilizationModelStochastic;
import org.cloudbus.cloudsim.vms.Vm;
import org.cloudbus.cloudsim.vms.VmSimple;
import org.cloudsimplus.autoscaling.HorizontalVmScaling;
import org.cloudsimplus.autoscaling.VerticalVmScaling;
import org.cloudsimplus.autoscaling.VerticalVmScalingSimple;
import org.cloudsimplus.builders.tables.CloudletsTableBuilder;
import org.cloudsimplus.listeners.EventInfo;
import org.cloudsimplus.listeners.EventListener;
import org.cloudsimplus.autoscaling.resources.ResourceScaling;
import org.cloudsimplus.autoscaling.resources.ResourceScalingGradual;
import org.cloudsimplus.autoscaling.resources.ResourceScalingInstantaneous;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import static java.util.Comparator.comparingDouble;
/**
* An example that scales VM IOPS up or down, according to the Cloudlet
* utilization model.
*
* Initially, we have a VM with given both upper and lower utilization
* thresholds. If the Cloudlet utilization model forces the VM to utilize more
* or less Iops than its thresholds, we vertically scale the VM IOPS resource in
* order to better use the Host resource.
*
* @author Kaio Oliveira
*/
public class VerticalVmIopsScalingExample {
private static final int SCHEDULING_INTERVAL = 1;
// Host
private static final int HOSTS = 1;
private static final int HOST_PES = 16;
private static final int HOST_IOPS_LIMIT = 100000;
// VM
private static final int VMS = 1;
private static final int VM_PES = 4;
private static final int VM_RAM = 1200;
// Thresholds
private static final double UPPER_THRESHOLD = 0.8;
private static final double LOWER_THRESHOLD = 0.2;
// Cloudlets
private static final int CLOUDLETS = 1;
private static final int CLOUDLETS_INITIAL_LENGTH = 100_000;
private static final int CLOUDLET_PES = 1;
private final CloudSim simulation;
private DatacenterBroker broker;
private List<Host> hostList;
private List<Vm> vmList;
private List<Cloudlet> cloudletList;
private int createdCloudlets;
private int createdVms;
public static void main(String[] args) {
new VerticalVmIopsScalingExample();
}
/**
* Default constructor that builds the simulation scenario and starts the
* simulation.
*/
private VerticalVmIopsScalingExample() {
/*
* You can remove the seed to get a dynamic one, based on current computer time.
* With a dynamic seed you will get different results at each simulation run.
*/
final long seed = 1;
hostList = new ArrayList<>(HOSTS);
vmList = new ArrayList<>(VMS);
// cloudletList = new ArrayList<>(CLOUDLETS);
cloudletList = createCloudlets();
simulation = new CloudSim();
simulation.addOnClockTickListener(this::onClockTickListener);
createDatacenter();
broker = new DatacenterBrokerSimple(simulation);
vmList.addAll(createListOfScalableVms(VMS));
// createCloudletListsWithDifferentDelays();
createCloudlets();
broker.submitVmList(vmList);
broker.submitCloudletList(cloudletList);
simulation.start();
printSimulationResults();
}
/**
* Shows updates every time the simulation clock advances.
*
* @param evt
* information about the event happened (that for this Listener is
* just the simulation time)
*/
private void onClockTickListener(EventInfo evt) {
vmList.forEach(vm -> {
Log.printFormatted("\t\tTime %6.1f: Vm %d Disk Usage: %6.2f%% (%2d IOPS. Running Cloudlets: #%d)\n",
evt.getTime(), vm.getId(),
vm.getIopsVerticalScaling().getResource().getPercentUtilization() * 100.0,
vm.getIops().getCapacity(), vm.getCloudletScheduler().getCloudletExecList().size());
});
}
private void printSimulationResults() {
final List<Cloudlet> finishedCloudlets = broker.getCloudletFinishedList();
final Comparator<Cloudlet> sortByVmId = comparingDouble(c -> c.getVm().getId());
final Comparator<Cloudlet> sortByStartTime = comparingDouble(Cloudlet::getExecStartTime);
finishedCloudlets.sort(sortByVmId.thenComparing(sortByStartTime));
new CloudletsTableBuilder(finishedCloudlets).build();
}
/**
* Creates a Datacenter and its Hosts.
*/
private void createDatacenter() {
for (int i = 0; i < HOSTS; i++) {
hostList.add(createHost());
}
Datacenter dc0 = new DatacenterSimple(simulation, hostList, new VmAllocationPolicySimple());
dc0.setSchedulingInterval(SCHEDULING_INTERVAL);
}
private Host createHost() {
List<Pe> peList = new ArrayList<>(HOST_PES);
for (int i = 0; i < HOST_PES; i++) {
peList.add(new PeSimple(1000, new PeProvisionerSimple()));
}
final long ram = 20000; // in Megabytes
final long bw = 100000; // in Megabytes
final long storage = 10000000; // in Megabites/s
final int id = hostList.size();
return new HostSimple(ram, HOST_IOPS_LIMIT, bw, storage, peList)
.setIopsProvisioner(new ResourceProvisionerShared()).setRamProvisioner(new ResourceProvisionerSimple())
.setBwProvisioner(new ResourceProvisionerSimple()).setVmScheduler(new VmSchedulerSpaceShared());
}
/**
* Creates a list of initial VMs in which each VM is able to scale vertically
* when it is over or underloaded.
*
* @param numberOfVms
* number of VMs to create
* @return the list of scalable VMs
* @see #createVerticalIopsScaling()
*/
private List<Vm> createListOfScalableVms(final int numberOfVms) {
List<Vm> scalableVmList = new ArrayList<>(numberOfVms);
for (int i = 0; i < numberOfVms; i++) {
Vm vm = createVm();
vm.setIopsVerticalScaling(createVerticalIopsScaling());
scalableVmList.add(vm);
}
return scalableVmList;
}
/**
* Creates a Vm object.
*
* @return the created Vm
*/
private Vm createVm() {
final int id = createdVms++;
final int initial_iops_limit = 1000;
return new VmSimple(id, 1000, VM_PES).setRam(VM_RAM).setBw(1000).setSize(10000)
.setCloudletScheduler(new CloudletSchedulerTimeShared()).setIops(initial_iops_limit);
}
/**
* 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;
}
/**
* Creates a list of Cloudlets.
*/
private List<Cloudlet> createCloudlets() {
final List<Cloudlet> list = new ArrayList<>(CLOUDLETS);
UtilizationModel utilization = new UtilizationModelFull();
for (int i = 0; i < CLOUDLETS; i++) {
Cloudlet cloudlet = new CloudletSimple(i, CLOUDLETS_INITIAL_LENGTH, CLOUDLET_PES).setFileSize(1024)
.setOutputSize(1024).setUtilizationModel(utilization).setUtilizationModelIops(utilization);
list.add(cloudlet);
}
return list;
}
}
\ No newline at end of file
package org.cloudbus.cloudsim.examples.autonomic.simulations;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.cloudbus.cloudsim.allocationpolicies.VmAllocationPolicyInfoAware;
import org.cloudbus.cloudsim.allocationpolicies.VmAllocationPolicySimple;
import org.cloudbus.cloudsim.brokers.DatacenterBroker;
import org.cloudbus.cloudsim.brokers.DatacenterBrokerSimple;
import org.cloudbus.cloudsim.cloudlets.Cloudlet;
import org.cloudbus.cloudsim.cloudlets.CloudletSimple;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.datacenters.Datacenter;
import org.cloudbus.cloudsim.datacenters.DatacenterSimple;
import org.cloudbus.cloudsim.hosts.Host;
import org.cloudbus.cloudsim.hosts.HostSimple;
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.Pe;
import org.cloudbus.cloudsim.resources.PeSimple;
import org.cloudbus.cloudsim.schedulers.cloudlet.CloudletSchedulerTimeShared;
import org.cloudbus.cloudsim.schedulers.vm.VmScheduler;
import org.cloudbus.cloudsim.schedulers.vm.VmSchedulerSpaceShared;
import org.cloudbus.cloudsim.util.Log;
import org.cloudbus.cloudsim.utilizationmodels.UtilizationModel;
import org.cloudbus.cloudsim.utilizationmodels.UtilizationModelFull;
import org.cloudbus.cloudsim.vms.Vm;
import org.cloudbus.cloudsim.vms.VmSimple;
import org.cloudbus.cloudsim.vms.VmWithMetadata;
import org.cloudbus.cloudsim.vms.VmWithMetadata.VmData;
import org.cloudbus.cloudsim.vms.VmWithMetadata.VmLabel;
import org.cloudsimplus.builders.tables.CloudletsTableBuilder;
import org.cloudsimplus.listeners.EventInfo;
public class InfoAwareWithUserError {
private static final int INFO_AWARE_INTERVAL = 1;
private static boolean flagInfoAware = true;
private static int placementInterval = 1;
private static int vmsPlacedID = 60;
private static final int NUMBER_HOSTS = 10;
private static final int HOSTS_PES = 13;
private static final long HOSTS_RAM = Integer.MAX_VALUE;
private static final long HOSTS_STORAGE = Integer.MAX_VALUE;
private static final long HOSTS_BW = Integer.MAX_VALUE;
private static final double HOSTS_MIPS = 100000;
private static final long HOSTS_IOPS = 500;
private static final int NUMBER_VMS_INITIAL = 60;
private static final double VMS_DELAY = 0.0;
private static final int VMS_PES = 1;
private static final long VMS_RAM = 10000; //1333;
private static final long VMS_STORAGE = 100000; //47500;
private static final long VMS_BW = 100000; //10000;
private static final long VMS_CPU_MIPS = 100000;
private static final long VMS_IO_MIPS = 1;
private static final long VMS_CPU_IOPS = 1;
private static final long VMS_IO_IOPS = 500;
private static final int NUMBER_CLOUDLETS_INITIAL = 60;
private static final double CLOUDLET_CPU_BOUND_DELAY = 0.0;
private static final int CLOUDLET_CPU_BOUND_LENGTH = 1000000000; //1000000000;
private static final int CLOUDLET_CPU_BOUND_PES = 1;
private static final int CLOUDLET_CPU_BOUND_IOPS = 1;
private static final double CLOUDLET_IO_BOUND_DELAY = 0.0;
private static final int CLOUDLET_IO_BOUND_LENGTH = 1;
private static final int CLOUDLET_IO_BOUND_PES = 1;
private static final int CLOUDLET_IO_BOUND_IOPS = 1666666;//5000000;
// private static final int VM_TOY_ID = 121;
// private static final double VM_TOY_DELAY = 0;
// private static final int VM_TOY_PES = 1;
// private static final long VM_TOY_RAM = 0;
// private static final long VM_TOY_STORAGE = 0;
// private static final long VM_TOY_BW = 100;
// private static final long VM_TOY_MIPS = 1;
// private static final long VM_TOY_IOPS = 0;
//
// private static final int CLOUDLET_TOY_ID = 0;
// private static final double CLOUDLET_TOY_DELAY = 0;
// private static final int CLOUDLET_TOY_LENGTH = 1;
// private static final int CLOUDLET_TOY_PES = 1;
// private static final int CLOUDLET_TOY_IOPS = 0;
private final CloudSim simulation;
private Datacenter datacenter;
private DatacenterBroker broker;
private List<Vm> vmList;
private List<Cloudlet> cloudletList;
private List<Host> hostList;
public static void main(String[] args) {
new InfoAwareWithUserError();
}
public InfoAwareWithUserError() {
Log.printFormattedLine("Starting %s ...", getClass().getSimpleName());
simulation = new CloudSim();
datacenter = createDatacenter(NUMBER_HOSTS);
//Creates a broker that is a software acting on behalf a cloud customer to manage his/her VMs and Cloudlets
broker = new DatacenterBrokerSimple(simulation);
vmList = new ArrayList<>(NUMBER_VMS_INITIAL);
int vmId = 0;
for (int i = 0; i < NUMBER_VMS_INITIAL/10; i++) {
for (int j = vmId; j < vmId + 5; j++) {
vmList.add(createVmSimple(j, VMS_DELAY, VMS_PES, VMS_CPU_MIPS, VMS_RAM,
VMS_BW, VMS_STORAGE, VMS_CPU_IOPS));
}
vmId += 5;
for (int j = vmId; j < vmId + 5; j++) {
vmList.add(createVmSimple(j, VMS_DELAY, VMS_PES, VMS_IO_MIPS, VMS_RAM,
VMS_BW, VMS_STORAGE, VMS_IO_IOPS));
}
vmId += 5;
}
// for (int i = 0; i < NUMBER_VMS_INITIAL/2; i++) {
// vmList.add(createVmSimple(i, VMS_DELAY, VMS_PES, VMS_CPU_MIPS, VMS_RAM,
// VMS_BW, VMS_STORAGE, VMS_CPU_IOPS));
// }
//
// for (int i = NUMBER_VMS_INITIAL/2; i < NUMBER_VMS_INITIAL; i++) {
// vmList.add(createVmSimple(i, VMS_DELAY, VMS_PES, VMS_IO_MIPS, VMS_RAM,
// VMS_BW, VMS_STORAGE, VMS_IO_IOPS));
// }
// vmList.add(createVmSimple(VM_TOY_ID, VM_TOY_DELAY, VM_TOY_PES, VM_TOY_MIPS, VM_TOY_RAM,
// VM_TOY_BW, VM_TOY_STORAGE, VM_TOY_IOPS));
broker.submitVmList(vmList);
cloudletList = new ArrayList<>(NUMBER_CLOUDLETS_INITIAL);
int cloudletId = 0;
for (int i = 0; i < NUMBER_CLOUDLETS_INITIAL/10; i++) {
for (int j = cloudletId; j < cloudletId + 5; j++) {
cloudletList.add(createCloudlets(j, CLOUDLET_CPU_BOUND_DELAY, CLOUDLET_CPU_BOUND_LENGTH,
CLOUDLET_CPU_BOUND_PES, CLOUDLET_CPU_BOUND_IOPS));
}
cloudletId += 5;
for (int j = cloudletId; j < cloudletId + 5; j++) {
cloudletList.add(createCloudlets(j, CLOUDLET_IO_BOUND_DELAY, CLOUDLET_IO_BOUND_LENGTH,
CLOUDLET_IO_BOUND_PES, CLOUDLET_IO_BOUND_IOPS));
}
cloudletId += 5;
}
// for (int i = 0; i < NUMBER_CLOUDLETS_INITIAL/2; i++) {
// cloudletList.add(createCloudlets(i, CLOUDLET_CPU_BOUND_DELAY, CLOUDLET_CPU_BOUND_LENGTH,
// CLOUDLET_CPU_BOUND_PES, CLOUDLET_CPU_BOUND_IOPS));
// }
//
// for (int i = NUMBER_CLOUDLETS_INITIAL/2; i < NUMBER_CLOUDLETS_INITIAL; i++) {
// cloudletList.add(createCloudlets(i, CLOUDLET_IO_BOUND_DELAY, CLOUDLET_IO_BOUND_LENGTH,
// CLOUDLET_IO_BOUND_PES, CLOUDLET_IO_BOUND_IOPS));
// }
// cloudletList.add(createCloudlets(CLOUDLET_TOY_ID, CLOUDLET_TOY_DELAY, CLOUDLET_TOY_LENGTH,
// CLOUDLET_TOY_PES, CLOUDLET_TOY_IOPS));
broker.submitCloudletList(cloudletList);
simulation.addOnClockTickListener(this::clockTickListener);
simulation.start();
final List<Cloudlet> finishedCloudlets = broker.getCloudletFinishedList();
new CloudletsTableBuilder(finishedCloudlets).build();
}
/**
* Event listener which is called every time the simulation clock advances.
* @param info information about the event happened.
*/
private void clockTickListener(final EventInfo info) {
final int time = (int)info.getTime();
if(time == INFO_AWARE_INTERVAL && flagInfoAware) {
Log.printLine("\n" + info.getTime() + ": # Changing Vm Allocation Policy to: Info-Aware\n");
datacenter = ((DatacenterSimple) datacenter).setVmAllocationPolicy(new VmAllocationPolicyInfoAware());
flagInfoAware = false;
}
/* Checks if the time specified in the scheduling interval has passed. */
if(time == placementInterval) {
Log.printLine("\n" + info.getTime() + ": # Placement of one IO-Bound and one CPU-Bound VM\n");
Vm vmIo = createVmIO(vmsPlacedID, VMS_DELAY, VMS_PES, VMS_IO_MIPS,
VMS_RAM, VMS_BW, VMS_STORAGE, VMS_IO_IOPS);
broker.submitVm(vmIo);
Cloudlet cloudletIo = createCloudlets(vmsPlacedID, CLOUDLET_IO_BOUND_DELAY, CLOUDLET_IO_BOUND_LENGTH,
CLOUDLET_IO_BOUND_PES, CLOUDLET_IO_BOUND_IOPS);
broker.submitCloudlet(cloudletIo);
vmsPlacedID++;
Vm vmCPU = createVmCPU(vmsPlacedID, VMS_DELAY, VMS_PES, VMS_CPU_MIPS,
VMS_RAM, VMS_BW, VMS_STORAGE, VMS_CPU_IOPS);
broker.submitVm(vmCPU);
Cloudlet cloudletCPU = createCloudlets(vmsPlacedID, CLOUDLET_CPU_BOUND_DELAY, CLOUDLET_CPU_BOUND_LENGTH,
CLOUDLET_CPU_BOUND_PES, CLOUDLET_CPU_BOUND_IOPS);
broker.submitCloudlet(cloudletCPU);