There are many methods of virtual machine allocation strategy in cloud computing. Now it is placed in the cloudsim project package with scheduling methods such as Random allocation, first fit, best fit and RoundRobin. The optimization process of virtual machine scheduling problem can also refer to the idea of multi-attribute decision-making. In this paper, the author attempts to use TOPSIS, a classical comprehensive evaluation index model in mathematical modeling, to solve the problem of virtual machine allocation strategy in cloud computing.
TOPSIS (technology for order preference by similarity to an ideal solution) the Chinese name of the model is "ranking method of approaching ideal solution", which is a method of ranking according to the proximity between the evaluation object and the idealized target. It is a distance comprehensive evaluation method. The basic idea is to calculate the distance between each sample and the positive and negative ideal solution by assuming the positive and negative ideal solution, obtain the relative closeness to the ideal scheme (that is, the closer to the positive ideal solution and the farther away from the negative ideal solution), and sort the advantages and disadvantages of each evaluation object. This paper selects three indicators as the criteria for selecting the best host, which are:
package org.cloudsimplus.examples; import org.cloudbus.cloudsim.allocationpolicies.VmAllocationPolicy; import org.cloudbus.cloudsim.allocationpolicies.VmAllocationPolicyAbstract; 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.PowerModelHost; import org.cloudbus.cloudsim.power.models.PowerModelHostSimple; import org.cloudbus.cloudsim.provisioners.PeProvisionerSimple; import org.cloudbus.cloudsim.provisioners.ResourceProvisioner; 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.VmSchedulerTimeShared; import org.cloudbus.cloudsim.utilizationmodels.UtilizationModel; import org.cloudbus.cloudsim.utilizationmodels.UtilizationModelDynamic; import org.cloudbus.cloudsim.utilizationmodels.UtilizationModelFull; import org.cloudbus.cloudsim.vms.HostResourceStats; import org.cloudbus.cloudsim.vms.Vm; import org.cloudbus.cloudsim.vms.VmSimple; import org.cloudsimplus.builders.tables.CloudletsTableBuilder; import java.util.*; import static java.util.Comparator.comparingLong; import java.util.List; public class VmAllocationPolicyTOPSISandPOWERExample_sherry { private static final int SCHEDULING_INTERVAL = 10; private static final int HOSTS = 30; private static final int HOST_PES =10; private static final int HOST_MIPS = 1000; private static final int VMS = 15; // Set the virtual machine Pe core to 4 or 5 // private static final int VM_PES = [4,5]; private static final int CLOUDLETS = 30; private static final int CLOUDLET_PES = 4; private static final int CLOUDLET_LENGTH = 50000; /** * Defines the power a Host uses, even if it's idle (in Watts). */ private static final double STATIC_POWER = 35; /** * The max power a Host uses (in Watts). */ private static final int MAX_POWER = 50; private final CloudSim simulation; private DatacenterBroker broker0; private List<Vm> vmList; private List<Cloudlet> cloudletList; private Datacenter datacenter0; private List<Host> hostList; public static void main(String[] args) { new VmAllocationPolicyTOPSISandPOWERExample_sherry(); } private VmAllocationPolicyTOPSISandPOWERExample_sherry(){ //Log.setLevel(Level.WARN); simulation = new CloudSim(); hostList = new ArrayList<>(HOSTS); datacenter0 = createDatacenterSimple(); //Creates a broker that is a software acting on behalf of a cloud customer to manage his/her VMs and Cloudlets broker0 = new DatacenterBrokerSimple(simulation); vmList = createVms(); cloudletList = createCloudlets(); broker0.submitVmList(vmList); broker0.submitCloudletList(cloudletList); simulation.start(); System.out.println("------------------------------- SIMULATION FOR SCHEDULING INTERVAL = " + SCHEDULING_INTERVAL+" -------------------------------"); final List<Cloudlet> finishedCloudlets = broker0.getCloudletFinishedList(); final Comparator<Cloudlet> hostComparator = comparingLong(cl -> cl.getVm().getHost().getId()); finishedCloudlets.sort(hostComparator.thenComparing(cl -> cl.getVm().getId())); new CloudletsTableBuilder(finishedCloudlets).build(); printHostsCpuUtilizationAndPowerConsumption(); } /** * The Host CPU Utilization History is only computed * if VMs utilization history is enabled by calling * {@code vm.getUtilizationHistory().enable()}. */ private void printHostsCpuUtilizationAndPowerConsumption() { System.out.println(); for (final Host host : hostList) { printHostCpuUtilizationAndPowerConsumption(host); } System.out.println(); } private void printHostCpuUtilizationAndPowerConsumption(final Host host) { final HostResourceStats cpuStats = host.getCpuUtilizationStats(); //The total Host's CPU utilization for the time specified by the map key final double utilizationPercentMean = cpuStats.getMean(); final double watts = host.getPowerModel().getPower(utilizationPercentMean); System.out.printf( "Host %2d CPU Usage mean: %6.1f%% | Power Consumption mean: %8.0f W%n", host.getId(), utilizationPercentMean * 100, watts); } /** * Creates a {@link Datacenter} and its {@link Host}s. */ private Datacenter createDatacenterSimple() { for(int i = 0; i < HOSTS; i++) { Host host = createPowerHost(i); hostList.add(host); } final Datacenter dc = new DatacenterSimple(simulation, hostList, new VmAllocationPolicyTOPSIS_sherry()); dc.setSchedulingInterval(SCHEDULING_INTERVAL); return dc; } private Host createPowerHost(final int id) { final List<Pe> peList = new ArrayList<>(HOST_PES); //List of Host's CPUs (Processing Elements, PEs) for (int i = 0; i < HOST_PES; i++) { peList.add(new PeSimple(1000, new PeProvisionerSimple())); } final long ram = 2048; //in Megabytes final long bw = 10000; //in Megabits/s final long storage = 1000000; //in Megabytes final ResourceProvisioner ramProvisioner = new ResourceProvisionerSimple(); final ResourceProvisioner bwProvisioner = new ResourceProvisionerSimple(); final VmScheduler vmScheduler = new VmSchedulerTimeShared(); final Host host = new HostSimple(ram, bw, storage, peList); final PowerModelHost powerModel = new PowerModelHostSimple(MAX_POWER, STATIC_POWER); host .setRamProvisioner(ramProvisioner) .setBwProvisioner(bwProvisioner) .setVmScheduler(vmScheduler) .setPowerModel(powerModel); host.setId(id); host.enableUtilizationStats(); return host; } /** * Creates a list of VMs. */ private List<Vm> createVms() { final List<Vm> list = new ArrayList<>(VMS); int VM_PES= getRandomVmPe(5); for (int i = 0; i < VMS; i++) { Vm vm = new VmSimple(i, 1000, VM_PES); vm.setRam(512).setBw(1000).setSize(10000) .setCloudletScheduler(new CloudletSchedulerTimeShared()); vm.enableUtilizationStats(); list.add(vm); } return list; } public int getRandomVmPe(final int maxValue){ Random rand=new Random(); //Let the Pe value range of Vm be a random number between [4,maxValue] int vm_pe=rand.nextInt(maxValue-4+1)+4; return vm_pe; } /** * Creates a list of Cloudlets. */ private List<Cloudlet> createCloudlets() { final List<Cloudlet> list = new ArrayList<>(CLOUDLETS); final UtilizationModel utilization = new UtilizationModelDynamic(0.2); for (int i = 0; i < CLOUDLETS; i++) { //Sets half of the cloudlets with the defined length and the other half with the double of it final long length = i < CLOUDLETS / 2 ? CLOUDLET_LENGTH : CLOUDLET_LENGTH * 2; Cloudlet cloudlet = new CloudletSimple(i, length, CLOUDLET_PES) .setFileSize(1024) .setOutputSize(1024) .setUtilizationModelCpu(new UtilizationModelFull()) .setUtilizationModelRam(utilization) .setUtilizationModelBw(utilization); list.add(cloudlet); } return list; } //=========================================form here is TOPSIS================================================================ public static class VmAllocationPolicyTOPSIS_sherry extends VmAllocationPolicyAbstract implements VmAllocationPolicy { long startTime = 0; //Record start time long endTime = 0; //Record end time long allTime = 0; //Record total time @Override protected Optional<Host> defaultFindHostForVm(final Vm vm) { final List<Host> hostList = getHostList(); Host temp = null; for (Host host : hostList) { HostResourceStats cpuUtilizationStats = host.getCpuUtilizationStats(); host.getBwUtilization(); host.getRamUtilization(); } startTime = System.currentTimeMillis(); // Create the data matrix of host as the input of TOPSIS. There are 4 columns in total, the first column is hostid, and the rest are 3 evaluation indicators // The storage form of hostData matrix is: // host_id | availability | load_balance | similarity HostMatrix hostMatrix=createData(hostList,vm); // start TOPSIS,get result matrix double result[]=TOPSIS(hostMatrix); // Select the host with the highest score int bestHostId= getBestHostId(result); Host host=hostList.get(bestHostId); endTime=System.currentTimeMillis(); allTime=endTime-startTime; if (host.isSuitableForVm(vm)){ temp=host; } return temp == null ? Optional.empty() :Optional.of(temp); } } private static int getBestHostId(double[] result){ double max=result[0]; int best=0; for (int i=1;i<result.length;i++){ if (result[i]>max){ max=result[i]; best=i; } } return best; } private static double[] TOPSIS(HostMatrix hostData){ //Step 1: eliminate dimension and standardize data processing HostMatrix standardMatrix=standard(hostData); //The weighted demand is proposed by the customer //Just provide a one-dimensional array of weight[target_nums] //Step 2: determine the positive ideal solution and negative ideal solution, and then obtain the comprehensive score of each host according to the formula double result[]=getScore(standardMatrix); return result; } private static HostMatrix standard(HostMatrix hostData){ int row,column; int num=hostData.getHostnum(hostData); int target=hostData.getTargetnum(hostData); double standard[][] = new double[num][target]; HostMatrix standardMatrix = new HostMatrix(num,target,standard); //Eliminate dimension and standardize data processing double down[] = new double[target]; double value,value2,value_sum; for (column=1;column<target;column++){ value_sum=0; for (row=0;row<num;row++){ value=hostData.getMatrix(row,column); value2=Math.pow(value,2); value_sum+=value2; } down[column]=Math.sqrt(value_sum); } for (row=0;row<num;row++){ for (column=0;column<target;column++){ if (column==0){ standardMatrix.setMatrix(row,column,row);//hostid System.out.print(row+" "); } else{ value=hostData.getMatrix(row,column)/down[column]; standardMatrix.setMatrix(row,column,value); System.out.print(value+" "); } } System.out.println(); } return standardMatrix; } private static double[] getScore(HostMatrix standardMaxtrix){ int num=standardMaxtrix.getHostnum(standardMaxtrix); int col=standardMaxtrix.getTargetnum(standardMaxtrix); int row,column; //Step 1: determine positive and negative ideal solutions (obtain the maximum and minimum values of each index) double max_targets[]=new double[col]; double min_targets[]=new double[col]; double max,min,value; for (column=1;column<col;column++){ max=standardMaxtrix.getMatrix(0,column); min=standardMaxtrix.getMatrix(0,column); for (row=1;row<num;num++){ value=standardMaxtrix.getMatrix(row,column); if (value>max) max=value; if (value<min) min=value; } max_targets[column]=max; min_targets[column]=min; } //Step 2: calculate score double DistanceToMax; double DistanceToMin; double host_score; double score[] =new double[num]; //Store the score of the ith evaluation object double distance_max,distance_min,value_max,value_min; for (row=0;row<num;row++){ distance_max=0; distance_min=0; for (column=1;column<num;column++){ value_max=standardMaxtrix.getMatrix(row,column)-max_targets[column]; distance_max+=Math.pow(value_max,2); value_min=standardMaxtrix.getMatrix(row,column)-min_targets[column]; distance_min+=Math.pow(value_min,2); } //Calculate the distance from data of all host s to positive and negative ideal solutions DistanceToMax=Math.sqrt(distance_max); DistanceToMin=Math.sqrt(distance_min); host_score=DistanceToMin/(DistanceToMax+DistanceToMin); score[row]=host_score; } return score; } private static HostMatrix createData(List<Host> hostList, Vm vm){ int PeSum = 0; long BwSum = 0; long RamSum = 0; for (int i = 0; i < hostList.size(); i++) { PeSum += hostList.get(i).getBusyPesNumber(); BwSum += hostList.get(i).getBw().getAllocatedResource(); RamSum += hostList.get(i).getRam().getAllocatedResource(); } //Record the mean values of Pe, Bw and Ram in the data center double PeAver = PeSum / hostList.size(); double BwAver = BwSum / hostList.size(); double RamAver = RamSum / hostList.size(); System.out.println(BwAver); int Matrix_row=hostList.size(); int Matrix_column=4; //There are 4 columns in the matrix, the first column is hostid, and the rest are 3 evaluation indexes double hostData[][] = new double[Matrix_row][Matrix_column]; HostMatrix hostMatrix = new HostMatrix(Matrix_row,Matrix_column,hostData); // The storage form of hostData matrix is: // host_id | availability | load_balance | similarity for (int row=0;row < Matrix_row; row++){ hostMatrix.setMatrix(row,0,row); hostMatrix.setMatrix(row,1,availability(hostList,row,vm)); hostMatrix.setMatrix(row,2,load_balance(hostList,row,PeAver,BwAver,RamAver)); hostMatrix.setMatrix(row,3,similarity(hostList,row,vm)); } return hostMatrix; } //The following are the evaluation indicators: //usability private static double availability(List<Host> hostList,int id,Vm vm){ long vmBw = vm.getBw().getCapacity(); long vmRam = vm.getRam().getCapacity(); long vmSize = vm.getStorage().getCapacity(); long bw = hostList.get(id).getBw().getAvailableResource(); long ram = hostList.get(id).getRam().getAvailableResource(); long storage = hostList.get(id).getStorage().getAvailableResource(); double distence = Math.sqrt(Math.pow(vmBw-bw,2) + Math.pow(vmRam-ram,2) + Math.pow(vmSize-storage,2)); return distence; } //load balancing private static double load_balance(List<Host> hostList,int id,double PeAver,double BwAver,double RamAver){ long bw = hostList.get(id).getBw().getAvailableResource(); long ram = hostList.get(id).getRam().getAvailableResource(); long pe = hostList.get(id).getBusyPesNumber(); double load = Math.sqrt(Math.pow(ram-RamAver,2) + Math.pow(bw-BwAver,2) + Math.pow(pe-PeAver,2)); return load; } //Similarity //Very small index private static double similarity(List<Host> hostList,int id,Vm vm){ long vmBw = vm.getBw().getCapacity(); long vmRam = vm.getRam().getCapacity(); long vmPe = vm.getNumberOfPes(); Host host = hostList.get(id); double similarity = 0; System.out.println(hostList.get(id).getRam().getAllocatedResource()); if(host.getRam().getAllocatedResource()!= 0 && host.getBw().getAllocatedResource() != 0&& host.getBusyPesNumber() != 0){ similarity = (vmRam / host.getRam().getAllocatedResource()) + (vmBw / host.getBw().getAllocatedResource()) + (vmPe / host.getBusyPesNumber()); if (similarity > 0.7) similarity = 1; //If it is too similar, give up changing the host; } //Since similarity is a very small indicator, the smaller the value, the better //It is necessary to forward the very small indicators, and the reverse method is used here System.out.println(similarity); return -similarity; } } //Define the host matrix class to store the values of three indicators class HostMatrix{ private int row;//that 's ok private int col;//column double [][]Data; public HostMatrix(int row, int col,double [][]Data) { this.row = row; this.col = col; this.Data = Data; } public void setMatrix(int row , int col, double value) { this.Data[row][col] = value; } public double getMatrix(int row, int col) { return Data[row][col] ; } public int getHostnum(HostMatrix hostMatrix){ return hostMatrix.Data.length; } public int getTargetnum(HostMatrix hostMatrix){ return hostMatrix.Data[0].length; } }