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

Merge branch 'development' into info-aware-simulation

parents e040d32d f6c99f28
/*
* CloudSim Plus: A modern, highly-extensible and easier-to-use Framework for
* Modeling and Simulation of Cloud Computing Infrastructures and Services.
* http://cloudsimplus.org
*
* Copyright (C) 2015-2018 Universidade da Beira Interior (UBI, Portugal) and
* the Instituto Federal de Educação Ciência e Tecnologia do Tocantins (IFTO, Brazil).
*
* This file is part of CloudSim Plus.
*
* CloudSim Plus is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CloudSim Plus is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CloudSim Plus. If not, see <http://www.gnu.org/licenses/>.
*/
package org.cloudbus.cloudsim.examples.autonomics;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.cloudbus.cloudsim.allocationpolicies.VmAllocationPolicy;
import org.cloudbus.cloudsim.allocationpolicies.VmAllocationPolicySimple;
import org.cloudbus.cloudsim.allocationpolicies.migration.VmAllocationPolicyMigrationWorstFitStaticThreshold;
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.power.models.PowerModelLinear;
import org.cloudbus.cloudsim.provisioners.PeProvisionerSimple;
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.VmSchedulerSpaceShared;
import org.cloudbus.cloudsim.schedulers.vm.VmSchedulerTimeShared;
import org.cloudbus.cloudsim.selectionpolicies.power.PowerVmSelectionPolicyMinimumUtilization;
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.vms.Vm;
import org.cloudbus.cloudsim.vms.VmSimple;
import org.cloudsimplus.slametrics.SLAMonitor;
import org.cloudsimplus.slametrics.SlaContract;
import org.cloudsimplus.builders.tables.CloudletsTableBuilder;
/**
* This example shows how to detect SLA violation from IOPS perspective.
*
* @author eduardolfalcao
*/
public final class IoMetricBeingViolatedExample {
private static final int SCHEDULE_TIME_TO_PROCESS_DATACENTER_EVENTS = 1;
private static final int HOST_MIPS_BY_PE = 1000;
private static final int HOST_NUMBER_OF_PES = 3;
private static final long HOST_RAM = 500000; //host memory (MB)
private static final long HOST_STORAGE = 1000000; //host storage
private static final long HOST_BW = 100000000L;
private static final long HOST_IOPS = 1000; //host io capacity
private static final int VM_MIPS = 1000;
private static final long VM_SIZE = 1000; //image size (MB)
private static final int VM_RAM = 10000; //vm memory (MB)
private static final long VM_BW = 100000;
private static final int VM_PES_NUM = 1; //number of cpus
private static final long VM_IOPS = 500;
private static final long CLOUDLET_LENGHT = 20000;
private static final long CLOUDLET_FILESIZE = 300;
private static final long CLOUDLET_OUTPUTSIZE = 300;
private static final int NUMBER_OF_HOSTS_TO_CREATE = 1;
private static final int NUMBER_OF_VMS_TO_CREATE = NUMBER_OF_HOSTS_TO_CREATE*3;
private static final int NUMBER_OF_CLOUDLETS_TO_CREATE_BY_VM = 1;
private final List<Vm> vmlist = new ArrayList<>();
private CloudSim simulation;
/**
* The file containing the SLA Contract in JSON format.
*/
public static final String METRICS_FILE = "src/main/resources/SlaCustomerAutonomics.json";
private SlaContract contract;
public static void main(String[] args) throws FileNotFoundException, IOException {
new IoMetricBeingViolatedExample();
}
private List<Cloudlet> cloudletList;
public IoMetricBeingViolatedExample() throws FileNotFoundException, IOException {
Log.printConcatLine("Starting ", IoMetricBeingViolatedExample.class.getSimpleName(), "...");
simulation = new CloudSim();
this.contract = SlaContract.getInstance(METRICS_FILE);
cloudletList = new ArrayList<>(NUMBER_OF_CLOUDLETS_TO_CREATE_BY_VM);
@SuppressWarnings("unused")
Datacenter datacenter0 = createDatacenter();
DatacenterBroker broker = new DatacenterBrokerSimple(simulation);
createAndSubmitVms(broker);
createAndSubmitCloudlets(broker);
simulation.start();
cpuUtilization(cloudletList);
new CloudletsTableBuilder(broker.getCloudletFinishedList()).build();
Log.printConcatLine(IoMetricBeingViolatedExample.class.getSimpleName(), " finished!");
for(int time = 0; time < simulation.clock(); time++){
for(Vm vm : this.vmlist){
System.out.println("Time: "+time+", vm: "+vm.getId()+" - violation = "+SLAMonitor.isTheIopsSlaBeingViolated(vm, time));
}
}
}
public void createAndSubmitCloudlets(DatacenterBroker broker) {
UtilizationModel utilizationModelFull = new UtilizationModelFull();
final int numberOfCloudlets = NUMBER_OF_VMS_TO_CREATE;
for (int i = 0; i < numberOfCloudlets; i++) {
Vm hostingVm = vmlist.get(i);
Cloudlet c = new CloudletSimple(
hostingVm.getId() + i, CLOUDLET_LENGHT, 2)
.setFileSize(CLOUDLET_FILESIZE)
.setOutputSize(CLOUDLET_OUTPUTSIZE)
.setUtilizationModelCpu(utilizationModelFull)
.setUtilizationModelRam(utilizationModelFull)
.setUtilizationModelBw(utilizationModelFull)
.setUtilizationModelIops(utilizationModelFull);
cloudletList.add(c);
broker.bindCloudletToVm(c, hostingVm);
}
broker.submitCloudletList(cloudletList);
}
public void createAndSubmitVms(DatacenterBroker broker) {
for (int i = 0; i < NUMBER_OF_VMS_TO_CREATE; i++) {
Vm vm = createVm(broker);
vmlist.add(vm);
}
broker.submitVmList(vmlist);
}
/**
*
* @param broker
* @return
*/
public Vm createVm(DatacenterBroker broker) {
VmSimple vm = new VmSimple(vmlist.size(), VM_MIPS, VM_PES_NUM);
vm.setContract(contract);
vm.setRam(VM_RAM).setBw(VM_BW).setIops(VM_IOPS).setSize(VM_SIZE)
.setCloudletScheduler(new CloudletSchedulerTimeShared());
vm.getUtilizationHistory().enable();
Log.printConcatLine(
"#Requested creation of VM ", vm.getId(), " with ", VM_MIPS, " MIPS x ", VM_PES_NUM);
return vm;
}
private Datacenter createDatacenter() {
final List<Host> hostList = new ArrayList<>();
for (int i = 0; i < NUMBER_OF_HOSTS_TO_CREATE; i++) {
hostList.add(createHost(i, HOST_NUMBER_OF_PES, HOST_MIPS_BY_PE));
Log.printConcatLine("#Created host ", i, " with ", HOST_MIPS_BY_PE, " mips x ", HOST_NUMBER_OF_PES);
}
Log.printLine();
VmAllocationPolicy allocationPolicy = new VmAllocationPolicySimple();
DatacenterSimple dc = new DatacenterSimple(simulation, hostList, allocationPolicy);
dc.enableMigrations().setSchedulingInterval(SCHEDULE_TIME_TO_PROCESS_DATACENTER_EVENTS);
return dc;
}
/**
*
* @param id
* @param numberOfPes
* @param mipsByPe
* @return
*
* @todo @author manoelcampos Using the {@link VmSchedulerSpaceShared} its
* getting NullPointerException, probably due to lack of CPU for all VMs. It
* has to be created an IT test to check this problem.
*
* @todo @author manoelcampos The method
* {@link DatacenterBroker#getCloudletFinishedList()} returns an empty list
* when using {@link DatacenterSimple},
* {@link Host} and {@link Vm}.
*/
public static Host createHost(int id, int numberOfPes, long mipsByPe) {
List<Pe> peList = createPeList(numberOfPes, mipsByPe);
Host host = new HostSimple(HOST_RAM, HOST_IOPS, HOST_BW, HOST_STORAGE, peList);
host.setPowerModel(new PowerModelLinear(1000, 0.7))
.setRamProvisioner(new ResourceProvisionerSimple())
.setBwProvisioner(new ResourceProvisionerSimple())
.setIopsProvisioner(new ResourceProvisionerShared())
.setVmScheduler(new VmSchedulerSpaceShared()); //FIXME SpaceShared may have a bug
host.enableStateHistory();
return host;
}
public static List<Pe> createPeList(int numberOfPEs, long mips) {
List<Pe> list = new ArrayList<>(numberOfPEs);
for (int i = 0; i < numberOfPEs; i++) {
list.add(new PeSimple(mips, new PeProvisionerSimple()));
}
return list;
}
/**
* Shows the cpu utilization
*
* @param cloudlet to calculate the utilization
* @return cpuUtilization
*/
private void cpuUtilization(List<Cloudlet> cloudlet) {
double cpuTime = 0;
for (Cloudlet cloudlets : cloudlet) {
cpuTime += cloudlets.getActualCpuTime();
}
Log.printFormattedLine("\n #Cpu utilization -> %f", (cpuTime * 100) / 100);
}
}
......@@ -132,10 +132,11 @@ public class VmsCpuUsageExample {
long bw = 1000;
//create two VMs
Vm vm = new VmSimple(id, mips, pesNumber);
VmSimple vm = new VmSimple(id, mips, pesNumber);
vm.setRam(ram).setBw(bw)
.setSize(size)
.setCloudletScheduler(new CloudletSchedulerTimeShared());
vm.getUtilizationHistory().enable();
return vm;
}
......@@ -144,7 +145,7 @@ public class VmsCpuUsageExample {
int numberOfUsageHistoryEntries = 0;
for (Vm vm : vmlist) {
Log.printFormattedLine("VM %d", vm.getId());
if (vm.getStateHistory().isEmpty()) {
if (vm.getUtilizationHistory().getHistory().isEmpty()) {
Log.printLine("\tThere isn't any usage history");
continue;
}
......@@ -187,7 +188,7 @@ public class VmsCpuUsageExample {
hostList.add(host);
}
return new DatacenterSimple(simulation, hostList, new VmAllocationPolicySimple());
return new DatacenterSimple(simulation, hostList, new VmAllocationPolicySimple()).setSchedulingInterval(1);
}
private static Host createHost(int pesNumber, long mips, int hostId) {
......@@ -201,9 +202,12 @@ public class VmsCpuUsageExample {
long storage = 1000000; //host storage
int bw = 10000;
return new HostSimple(ram, bw, storage, peList)
.setRamProvisioner(new ResourceProvisionerSimple())
.setBwProvisioner(new ResourceProvisionerSimple())
.setVmScheduler(new VmSchedulerTimeShared());
Host h = new HostSimple(ram, bw, storage, peList)
.setRamProvisioner(new ResourceProvisionerSimple())
.setBwProvisioner(new ResourceProvisionerSimple())
.setVmScheduler(new VmSchedulerTimeShared());
h.enableStateHistory();
return h;
}
}
{
"metrics": [
{
"name": "IOPSProvisioned",
"dimensions": [
{
"name": "minValue",
"value": 1000,
"unit": "Iops"
}
]
}
]
}
\ No newline at end of file
......@@ -111,7 +111,8 @@ public final class VmMigrationWhenCpuMetricIsViolatedExample {
/**
* The file containing the SLA Contract in JSON format.
*/
public static final String METRICS_FILE = "SlaMetrics.json";
// public static final String METRICS_FILE = "SlaMetrics.json";
public static final String METRICS_FILE = "SlaCustomer0.json";
private SlaContract contract;
......
......@@ -374,6 +374,7 @@ public abstract class DatacenterBrokerAbstract extends CloudSimEntity implements
setSimulationForUtilizationModelIfNotSet(c.getUtilizationModelCpu());
setSimulationForUtilizationModelIfNotSet(c.getUtilizationModelBw());
setSimulationForUtilizationModelIfNotSet(c.getUtilizationModelRam());
setSimulationForUtilizationModelIfNotSet(c.getUtilizationModelIops());
}
}
......
......@@ -184,7 +184,7 @@ public class CloudSim implements Simulation {
// NOTE: the order for the lines below is important
this.calendar = Calendar.getInstance();
this.cis = new CloudInformationService(this);
this.cis = new CloudInformationService(this);
if (minTimeBetweenEvents <= 0) {
throw new IllegalArgumentException("The minimal time between events should be positive, but is:" + minTimeBetweenEvents);
......
......@@ -971,11 +971,16 @@ public class HostSimple implements Host {
"%.2f: [%s] %.0f MIPS not allocated for each one of the %d PEs from %s due to %s.",
getSimulation().clock(), this, notAllocatedMipsByPe, vm.getNumberOfPes(), vm, reason);
}
double totalAllocatedIops = iopsProvisioner.getAllocatedResourceForVm(vm);
double totalRequestedIops = vm.getCurrentRequestedIops();
final VmStateHistoryEntry entry = new VmStateHistoryEntry(
currentTime,
totalAllocatedMips,
totalRequestedMips,
totalAllocatedIops,
totalRequestedIops,
vm.isInMigration() && !getVmsMigratingIn().contains(vm));
vm.addStateHistoryEntry(entry);
......
......@@ -73,16 +73,6 @@ public class ResourceProvisionerShared extends ResourceProvisionerAbstract {
deallocateResourceForVm(vm);
}
/*
Pe resources are not stored in the VM resource List.
Only the provisioner keeps track of Pe allocation for VM.
This way, if the resource is not found inside the VM
and it is a Pe, it's OK (as it is expected)
*/
if(!getResource().isObjectSubClassOf(Pe.class) && !vm.getResource(getResourceClass()).setCapacity(newTotalVmResourceCapacity)){
return false;
}
//Allocates the requested resource from the physical resource
getResource().allocateResource(newTotalVmResourceCapacity);
getResourceAllocationMap().put(vm, newTotalVmResourceCapacity);
......
......@@ -1037,9 +1037,9 @@ public abstract class CloudletSchedulerAbstract implements CloudletScheduler {
public double getCurrentRequestedIopsPercentUtilization() {
return cloudletExecList.stream()
.map(CloudletExecution::getCloudlet)
.map(Cloudlet::getUtilizationModelIops) //TODO Implement getUtilizationModelIops
.map(Cloudlet::getUtilizationModelIops)
.mapToDouble(um -> getAbsoluteCloudletResourceUtilization(um, vm.getIops().getCapacity()))
.sum() / vm.getBw().getCapacity();
.sum() / vm.getIops().getCapacity();
}
@Override
......
......@@ -17,13 +17,15 @@ import org.cloudbus.cloudsim.resources.*;
import org.cloudbus.cloudsim.schedulers.cloudlet.CloudletScheduler;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import org.cloudbus.cloudsim.core.CustomerEntity;
import org.cloudbus.cloudsim.core.CustomerEntity;
import org.cloudsimplus.autoscaling.VerticalVmScaling;
import org.cloudsimplus.listeners.VmHostEventInfo;
import org.cloudsimplus.listeners.VmDatacenterEventInfo;
import org.cloudsimplus.listeners.EventListener;
import org.cloudsimplus.slametrics.SlaContract;
/**
* An interface to be implemented by each class that provides basic
......@@ -316,6 +318,7 @@ public interface Vm extends Machine, UniquelyIdentificable, Comparable<Vm>, Cust
/**
* Gets a <b>read-only</b> list with the history of requests and allocation of MIPS for this VM.
* the key is the time, and the value the history itself
*
* @return the state history
*/
......@@ -744,4 +747,8 @@ public interface Vm extends Machine, UniquelyIdentificable, Comparable<Vm>, Cust
* @see UtilizationHistory#enable()
*/
UtilizationHistory getUtilizationHistory();
SlaContract getContract();
void setContract(SlaContract contract);
}
......@@ -13,9 +13,11 @@ import org.cloudsimplus.autoscaling.VerticalVmScaling;
import org.cloudsimplus.listeners.EventListener;
import org.cloudsimplus.listeners.VmDatacenterEventInfo;
import org.cloudsimplus.listeners.VmHostEventInfo;
import org.cloudsimplus.slametrics.SlaContract;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* A class that implements the Null Object Design Pattern for {@link Vm}
......@@ -158,7 +160,7 @@ final class VmNull implements Vm {
@Override public Vm setSize(long size) {
return this;
}
@Override public double updateProcessing(double currentTime, List<Double> mipsShare, double iops) {
@Override public double updateProcessing(double currentTime, List<Double> mipsShare) {
return 0.0;
}
@Override public Vm setCloudletScheduler(CloudletScheduler cloudletScheduler) {
......@@ -233,8 +235,14 @@ final class VmNull implements Vm {
return null;
}
@Override
public double updateProcessing(double currentTime, List<Double> mipsShare) {
// TODO Auto-generated method stub
public SlaContract getContract() {
return null;
}
@Override
public void setContract(SlaContract contract) { }
@Override
public double updateProcessing(double currentTime, List<Double> mipsShare,
double iops) {
return 0;
}
}
}
......@@ -21,6 +21,7 @@ import org.cloudsimplus.autoscaling.VmScaling;
import org.cloudsimplus.listeners.VmHostEventInfo;
import org.cloudsimplus.listeners.VmDatacenterEventInfo;
import org.cloudsimplus.listeners.EventListener;
import org.cloudsimplus.slametrics.SlaContract;
import org.cloudbus.cloudsim.resources.*;
import org.cloudbus.cloudsim.schedulers.cloudlet.CloudletScheduler;
......@@ -106,6 +107,11 @@ public class VmSimple implements Vm {
* The VM's IOPS resource capacity.
*/
private Iops iops;
/**
* The SLA regarding this VM.
*/
protected SlaContract contract;
/**
* @see #getSubmissionDelay()
......@@ -505,6 +511,14 @@ public class VmSimple implements Vm {
setBw(new Bandwidth(bwCapacity));
return this;
}
public SlaContract getContract() {
return contract;
}
public void setContract(SlaContract contract) {
this.contract = contract;
}
@Override
public Resource getStorage() {
......@@ -621,12 +635,6 @@ public class VmSimple implements Vm {
@Override
public List<VmStateHistoryEntry> getStateHistory() {
/*
* @todo Instead of using a list, this attribute would be a map, where the
* key can be the history time and the value the history itself. This
* way, if one wants to get the history for a given time, he/she doesn't
* have to iterate over the entire list to find the desired entry.
*/
return Collections.unmodifiableList(stateHistory);
}
......
......@@ -29,6 +29,16 @@ public class VmStateHistoryEntry {
* The requested mips.
*/
private double requestedMips;
/**
* The allocated iops.
*/
private double allocatedIops;
/**
* The requested iops.
*/
private double requestedIops;
/**
* The is in migration.
......@@ -49,6 +59,20 @@ public class VmStateHistoryEntry {
setRequestedMips(requestedMips);
setInMigration(inMigration);
}
/**
* Instantiates a new VmStateHistoryEntry
*
* @param time the time
* @param allocatedMips the allocated mips
* @param requestedMips the requested mips
* @param inMigration the is in migration
*/
public VmStateHistoryEntry(double time, double allocatedMips, double requestedMips, double allocatedIops, double requestedIops, boolean inMigration) {
this(time,allocatedMips,requestedMips,inMigration);
setAllocatedIops(allocatedIops);
setRequestedIops(requestedIops);
}
/**
* Sets the time.
......@@ -103,6 +127,14 @@ public class VmStateHistoryEntry {
public double getRequestedMips() {
return requestedMips;
}
public void setRequestedIops(double requestedIops) {
this.requestedIops = requestedIops;
}
public void setAllocatedIops(double allocatedIops) {
this.allocatedIops = allocatedIops;
}
/**