Using TOPSIS comprehensive evaluation scoring model to realize virtual machine allocation policy (non portable) vmallocation policy in cloudsim

Keywords: Java IntelliJ IDEA cloud computing Mathematical Modeling

         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:

(1) availability: defined as the host with the most remaining available resources, that is, the VM is placed on the host with the most remaining resources.
(2) Load balancing_ Balance: defined as the distance or variance between a single host load (considering CPU, memory and bandwidth) and the average load of all hosts in the data center.
(3) Similarity: calculate the resource request similarity between the virtual machine to be migrated and the virtual machine on the host, set a threshold, and give up selecting the host if it is too similar.
        Comprehensively score the host through the above indicators, give the resource with the highest score to Vm, and output the time to find the resource using the algorithm and the host energy consumption table.
The following is an example code of implementing virtual machine allocation strategy using TOPSIS:
VmAllocationPolicyTOPSISandPOWERExample_sherry.java
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;
        }
    }

Posted by slysop on Thu, 21 Oct 2021 20:12:14 -0700