Динамическое добавление Cloudlets к той же виртуальной машине, которая уже запущена (после CloudSim.startSimulation())

В CloudSimExample7,

package org.cloudbus.cloudsim.examples;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.LinkedList;
import java.util.List;

import org.cloudbus.cloudsim.Cloudlet;
import org.cloudbus.cloudsim.CloudletSchedulerTimeShared;
import org.cloudbus.cloudsim.Datacenter;
import org.cloudbus.cloudsim.DatacenterBroker;
import org.cloudbus.cloudsim.DatacenterCharacteristics;
import org.cloudbus.cloudsim.Host;
import org.cloudbus.cloudsim.Log;
import org.cloudbus.cloudsim.Pe;
import org.cloudbus.cloudsim.Storage;
import org.cloudbus.cloudsim.UtilizationModel;
import org.cloudbus.cloudsim.UtilizationModelFull;
import org.cloudbus.cloudsim.Vm;
import org.cloudbus.cloudsim.VmAllocationPolicySimple;
import org.cloudbus.cloudsim.VmSchedulerTimeShared;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.provisioners.BwProvisionerSimple;
import org.cloudbus.cloudsim.provisioners.PeProvisionerSimple;
import org.cloudbus.cloudsim.provisioners.RamProvisionerSimple;

/**
* An example showing how to pause and resume the simulation,
* and create simulation entities (a DatacenterBroker in this example)
* dynamically.
*/
public class CloudSimExample7 {

/** The cloudlet list. */
private static List<Cloudlet> cloudletList;

/** The vmlist. */
private static List<Vm> vmlist;

private static List<Vm> createVM(int userId, int vms, int idShift) {
    //Creates a container to store VMs. This list is passed to the broker later
    LinkedList<Vm> list = new LinkedList<Vm>();

    //VM Parameters
    long size = 10000; //image size (MB)
    int ram = 512; //vm memory (MB)
    int mips = 250;
    long bw = 1000;
    int pesNumber = 1; //number of cpus
    String vmm = "Xen"; //VMM name

    //create VMs
    Vm[] vm = new Vm[vms];

    for(int i=0;i<vms;i++){
        vm[i] = new Vm(idShift + i, userId, mips, pesNumber, ram, bw, size, vmm, new CloudletSchedulerTimeShared());
        list.add(vm[i]);
    }

    return list;
}


private static List<Cloudlet> createCloudlet(int userId, int cloudlets, int idShift){
    // Creates a container to store Cloudlets
    LinkedList<Cloudlet> list = new LinkedList<Cloudlet>();

    //cloudlet parameters
    long length = 40000;
    long fileSize = 300;
    long outputSize = 300;
    int pesNumber = 1;
    UtilizationModel utilizationModel = new UtilizationModelFull();

    Cloudlet[] cloudlet = new Cloudlet[cloudlets];

    for(int i=0;i<cloudlets;i++){
        cloudlet[i] = new Cloudlet(idShift + i, length, pesNumber, fileSize, outputSize, utilizationModel, utilizationModel, utilizationModel);
        // setting the owner of these Cloudlets
        cloudlet[i].setUserId(userId);
        list.add(cloudlet[i]);
    }

    return list;
}


////////////////////////// STATIC METHODS ///////////////////////

/**
 * Creates main() to run this example
 */
public static void main(String[] args) {
    Log.printLine("Starting CloudSimExample7...");

    try {
        // First step: Initialize the CloudSim package. It should be called
        // before creating any entities.
        int num_user = 2;   // number of grid users
        Calendar calendar = Calendar.getInstance();
        boolean trace_flag = false;  // mean trace events

        // Initialize the CloudSim library
        CloudSim.init(num_user, calendar, trace_flag);

        // Second step: Create Datacenters
        //Datacenters are the resource providers in CloudSim. We need at list one of them to run a CloudSim simulation
        @SuppressWarnings("unused")
        Datacenter datacenter0 = createDatacenter("Datacenter_0");
        @SuppressWarnings("unused")
        Datacenter datacenter1 = createDatacenter("Datacenter_1");

        //Third step: Create Broker
        DatacenterBroker broker = createBroker("Broker_0");
        int brokerId = broker.getId();

        //Fourth step: Create VMs and Cloudlets and send them to broker
        vmlist = createVM(brokerId, 5, 0); //creating 5 vms
        cloudletList = createCloudlet(brokerId, 10, 0); // creating 10 cloudlets

        broker.submitVmList(vmlist);
        broker.submitCloudletList(cloudletList);

        // A thread that will create a new broker at 200 clock time
        Runnable monitor = new Runnable() {
            @Override
            public void run() {
                CloudSim.pauseSimulation(200);
                while (true) {
                    if (CloudSim.isPaused()) {
                        break;
                    }
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                Log.printLine("\n\n\n" + CloudSim.clock() + ": The simulation is paused for 5 sec \n\n");

                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                **DatacenterBroker broker = createBroker("Broker_1");
                int brokerId = broker.getId();
                //Create VMs and Cloudlets and send them to broker
                vmlist = createVM(brokerId, 5, 100); //creating 5 vms
                cloudletList = createCloudlet(brokerId, 10, 100); // creating 10 cloudlets
                broker.submitVmList(vmlist);
                broker.submitCloudletList(cloudletList);
                CloudSim.resumeSimulation();**
            }
        };

        new Thread(monitor).start();
        Thread.sleep(1000);

        // Fifth step: Starts the simulation
        CloudSim.startSimulation();

        // Final step: Print results when simulation is over
        List<Cloudlet> newList = broker.getCloudletReceivedList();

        CloudSim.stopSimulation();

        printCloudletList(newList);

        Log.printLine("CloudSimExample7 finished!");
    }
    catch (Exception e)
    {
        e.printStackTrace();
        Log.printLine("The simulation has been terminated due to an unexpected error");
    }
}

private static Datacenter createDatacenter(String name){

    // Here are the steps needed to create a PowerDatacenter:
    // 1. We need to create a list to store one or more
    //    Machines
    List<Host> hostList = new ArrayList<Host>();

    // 2. A Machine contains one or more PEs or CPUs/Cores. Therefore, should
    //    create a list to store these PEs before creating
    //    a Machine.
    List<Pe> peList1 = new ArrayList<Pe>();

    int mips = 1000;

    // 3. Create PEs and add these into the list.
    //for a quad-core machine, a list of 4 PEs is required:
    peList1.add(new Pe(0, new PeProvisionerSimple(mips))); // need to store Pe id and MIPS Rating
    peList1.add(new Pe(1, new PeProvisionerSimple(mips)));
    peList1.add(new Pe(2, new PeProvisionerSimple(mips)));
    peList1.add(new Pe(3, new PeProvisionerSimple(mips)));

    //Another list, for a dual-core machine
    List<Pe> peList2 = new ArrayList<Pe>();

    peList2.add(new Pe(0, new PeProvisionerSimple(mips)));
    peList2.add(new Pe(1, new PeProvisionerSimple(mips)));

    //4. Create Hosts with its id and list of PEs and add them to the list of machines
    int hostId=0;
    int ram = 16384; //host memory (MB)
    long storage = 1000000; //host storage
    int bw = 10000;

    hostList.add(
            new Host(
                hostId,
                new RamProvisionerSimple(ram),
                new BwProvisionerSimple(bw),
                storage,
                peList1,
                new VmSchedulerTimeShared(peList1)
            )
        ); // This is our first machine

    hostId++;

    hostList.add(
            new Host(
                hostId,
                new RamProvisionerSimple(ram),
                new BwProvisionerSimple(bw),
                storage,
                peList2,
                new VmSchedulerTimeShared(peList2)
            )
        ); // Second machine

    // 5. Create a DatacenterCharacteristics object that stores the
    //    properties of a data center: architecture, OS, list of
    //    Machines, allocation policy: time- or space-shared, time zone
    //    and its price (G$/Pe time unit).
    String arch = "x86";      // system architecture
    String os = "Linux";          // operating system
    String vmm = "Xen";
    double time_zone = 10.0;         // time zone this resource located
    double cost = 3.0;              // the cost of using processing in this resource
    double costPerMem = 0.05;       // the cost of using memory in this resource
    double costPerStorage = 0.1;    // the cost of using storage in this resource
    double costPerBw = 0.1;         // the cost of using bw in this resource
    LinkedList<Storage> storageList = new LinkedList<Storage>();    //we are not adding SAN devices by now

    DatacenterCharacteristics characteristics = new DatacenterCharacteristics(
            arch, os, vmm, hostList, time_zone, cost, costPerMem, costPerStorage, costPerBw);


    // 6. Finally, we need to create a PowerDatacenter object.
    Datacenter datacenter = null;
    try {
        datacenter = new Datacenter(name, characteristics, new VmAllocationPolicySimple(hostList), storageList, 0);
    } catch (Exception e) {
        e.printStackTrace();
    }

    return datacenter;
}

//We strongly encourage users to develop their own broker policies, to submit vms and cloudlets according
//to the specific rules of the simulated scenario
private static DatacenterBroker createBroker(String name){

    DatacenterBroker broker = null;
    try {
        broker = new DatacenterBroker(name);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
    return broker;
}

/**
 * Prints the Cloudlet objects
 * @param list  list of Cloudlets
 */
private static void printCloudletList(List<Cloudlet> list) {
    int size = list.size();
    Cloudlet cloudlet;

    String indent = "    ";
    Log.printLine();
    Log.printLine("========== OUTPUT ==========");
    Log.printLine("Cloudlet ID" + indent + "STATUS" + indent +
            "Data center ID" + indent + "VM ID" + indent + indent + "Time" + indent + "Start Time" + indent + "Finish Time");

    DecimalFormat dft = new DecimalFormat("###.##");
    for (int i = 0; i < size; i++) {
        cloudlet = list.get(i);
        Log.print(indent + cloudlet.getCloudletId() + indent + indent);

        if (cloudlet.getCloudletStatus() == Cloudlet.SUCCESS){
            Log.print("SUCCESS");

            Log.printLine( indent + indent + cloudlet.getResourceId() + indent + indent + indent + cloudlet.getVmId() +
                    indent + indent + indent + dft.format(cloudlet.getActualCPUTime()) +
                    indent + indent + dft.format(cloudlet.getExecStartTime())+ indent + indent + indent + dft.format(cloudlet.getFinishTime()));
        }
    }

}
}

Здесь создается новый брокер, добавляются новые виртуальные машины, и этим новым виртуальным машинам назначаются новые облака. Ниже приведен фрагмент кода для того же.

Runnable monitor = new Runnable() {
    @Override
    public void run() {
        CloudSim.pauseSimulation(200);
        while (true) {
            if (CloudSim.isPaused()) {
                break;
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        Log.printLine("\n\n\n" + CloudSim.clock() + ": The simulation is paused for 5 sec \n\n");

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        DatacenterBroker broker = createBroker("Broker_1");
        int brokerId = broker.getId();

        //Create VMs and Cloudlets and send them to broker
        vmlist = createVM(brokerId, 5, 100); //creating 5 vms
        cloudletList = createCloudlet(brokerId, 10, 100); // creating 10 cloudlets

        broker.submitVmList(vmlist);
        broker.submitCloudletList(cloudletList);

        CloudSim.resumeSimulation();
    }
};

Но то, что я пытаюсь сделать, похоже на это.

Runnable monitor = new Runnable() {
    @Override
    public void run() {
        CloudSim.pauseSimulation(200);
        while (true) {
            if (CloudSim.isPaused()) {
                break;
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        Log.printLine("\n\n\n" + CloudSim.clock() + ": The simulation is paused for 5 sec \n\n");

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        /*
            The vmList, broker and brokerID are already defined in Main Thread and are available.

        */            

        cloudletList = createCloudlet(brokerId, 10, 100); // creating 10 cloudlets

        broker.submitVmList(vmlist);
        broker.submitCloudletList(cloudletList);

        CloudSim.resumeSimulation();
    }
};

Это потому, что мое требование

  • Для динамического создания облака в отдельном потоке (основной поток используется для Cloudsim.startSimulation())
  • Добавьте эти новые облака к существующим виртуальным машинам, которые работают.

person Sameer Kulkarni    schedule 25.11.2016    source источник
comment
В чем дело? Какой у Вас вопрос? Какое поведение вы ожидаете по сравнению с тем, что вы получаете?   -  person Heri    schedule 25.11.2016
comment
Моя проблема в том, что я не могу добавить Cloudlets во время выполнения к работающим виртуальным машинам. Это дает мне ошибку. Мой вопрос: можно ли добавлять Cloudlets во время выполнения к одной и той же виртуальной машине, если да, то как?   -  person Sameer Kulkarni    schedule 26.11.2016


Ответы (1)


Используя CloudSim Plus, вы можете отложить отправку Cloudlets и виртуальных машин, позвонив по номеру broker.submitCloudletList(cloudletList, delayInSeconds). Если вы хотите динамически создавать Cloudlets после начала моделирования, вы можете использовать для этого один из многих слушателей CloudSim Plus. Вы можете добавить метод для создания новых Cloudlets, например:

private void createDynamicCloudlet(EventInfo evt) {
    if((int)evt.getTime() == 100){
        List<Cloudlet> newCloudletList = new ArrayList<>();
        System.out.printf("\n# Dynamically creating 2 Cloudlets at time %.2f\n", evt.getTime());
        Cloudlet cloudlet1 = new CloudletSimple(1000, 2);
        newCloudletList(cloudlet1);
        Cloudlet cloudlet2 = new CloudletSimple(1000, 2);
        newCloudletList(cloudlet2);
        broker0.submitCloudletList(newCloudletList);
    }
}

Затем вы вызываете simulation.addOnClockTickListener(this::createDynamicCloudletAndVm) перед запуском симуляции. Это приведет к тому, что метод createDynamicCloudlet будет вызываться каждый раз, когда часы симуляции увеличиваются. Если часы достигают 100 секунд, создается новый Cloudlet и отправляется уже существующему брокеру.

Вам не нужно менять классы фреймворка, добавлять новый экземпляр брокера или использовать потоки для такой задачи. Вы можете проверить весь пример здесь.

Если пример был полезен, пожалуйста, проголосуйте.

person Manoel Campos    schedule 09.11.2018