Cloudism3.0.3学习与使用(二)

三、Example1 和VmAllocationPolicySimple源码分析

  在接着上一篇博客分析之前,我们先来了解一些可能会需要注意的地方。
  MIPS是虚拟机的cpu处理速度。假设同一机器下的所有PE具有相同的MIPS评级。Pe(处理单元)表示CPU单元,即可以理解为CPU的核数,按照每秒百万指令(MIPS)评级定义。
  mips是虚拟机的cpu处理速度,cloudlet的length / 虚拟机mips = 任务执行所需时间,所有虚拟机的mips之和不能超过datacenter中定义的主机的物理cpu的mips之和,而虚拟cpu的mips的最大值也不能超过物理cpu的最大值,否则虚拟机将创建失败。

CloudSimExample1

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.examples.VmAllocationPolicyFirstIn;
import org.cloudbus.cloudsim.examples.VmAllocationPolicy_BestFit;
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;
/**
 * A simple example showing how to create a datacenter with one host and run one
 * cloudlet on it.
 */
public class CloudSimExample1 {

    /** The cloudlet list. */
    private static List<Cloudlet> cloudletList;
    /** The vmlist. */
    private static List<Vm> vmlist;
    int algorithm_flag=0;
    static List<Host> hostList = new ArrayList<Host>();
    /**
     * Creates main() to run this example.
     *
     * @param args the args
     */

    @SuppressWarnings("unused")
    public static void main(String[] args) {

        Log.printLine("Starting CloudSimExample1...");

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

            // Initialize the CloudSim library 初始化CloudSim包
            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
            Datacenter datacenter0 = createDatacenter("Datacenter_0");

            // Third step: Create Broker 数据中心代理
            //DatacenterBroker模拟SaaS提供商代理,根据QoS的需求协商资源和服务的分配策略
            DatacenterBroker broker = createBroker();
            int brokerId = broker.getId();

            // Fourth step: Create one virtual machine
            vmlist = new ArrayList<Vm>();

            // VM description
            int vmid = 0;
            int mips = 3000;
            long size = 10000; // image size (MB)
            int ram = 1024; // vm memory (MB)
            long bw = 1000;
            int pesNumber1 = 2; // number of cpus
            int pesNumber2 = 3; // number of cpus
            int pesNumber3 = 3; // number of cpus
            int pesNumber4 = 1; // number of cpus
            String vmm = "Xen"; // VMM name

            //create two VMs
            Vm vm1 = new Vm(vmid, brokerId, mips, pesNumber1, ram, bw, size, vmm, new CloudletSchedulerTimeShared());
            vmid++;
            Vm vm2 = new Vm(vmid, brokerId, mips, pesNumber2, ram, bw, size, vmm, new CloudletSchedulerTimeShared());
            vmid++;
            Vm vm3 = new Vm(vmid, brokerId, mips, pesNumber3, ram, bw, size, vmm, new CloudletSchedulerTimeShared());
            vmid++;
            Vm vm4 = new Vm(vmid, brokerId, mips, pesNumber4, ram, bw, size, vmm, new CloudletSchedulerTimeShared());
            // add the VM to the vmList
            vmlist.add(vm1);
            vmlist.add(vm2);
            vmlist.add(vm3);
            vmlist.add(vm4);
            // submit vm list to the broker 提交虚拟机列表
            broker.submitVmList(vmlist);

            // Fifth step: Create one Cloudlet  云服务
            cloudletList = new ArrayList<Cloudlet>();

            // Cloudlet properties
            int id = 0;
            long length = 400000;
            long fileSize = 300;
            long outputSize = 300;
            int pesNumber = 1; // number of cpus
            UtilizationModel utilizationModel = new UtilizationModelFull(); //类:根据时间返回百分比利用率。

            Cloudlet cloudlet = new Cloudlet(id, length, pesNumber, fileSize, outputSize, utilizationModel, utilizationModel, utilizationModel);
            cloudlet.setUserId(brokerId);
            cloudlet.setVmId(vmid);

            // add the cloudlet to the list
            cloudletList.add(cloudlet);

            // submit cloudlet list to the broker 向代理提交任务列表
            broker.submitCloudletList(cloudletList);

            // Sixth step: Starts the simulation(模拟)
            CloudSim.startSimulation();

            CloudSim.stopSimulation();

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

            Log.printLine("CloudSimExample1 finished!");
        } catch (Exception e) {
            e.printStackTrace();
            Log.printLine("Unwanted errors happen");
        }
    }

    /**
     * Creates the datacenter.
     *
     * @param name the name
     *
     * @return the datacenter
     */
    private static Datacenter createDatacenter(String name) {

        // Here are the steps needed to create a PowerDatacenter:
        // 1. We need to create a list to store our machine

        // 2. A Machine contains one or more PEs or CPUs/Cores.
        // In this example, it will have only one core.
        List<Pe> peList = new ArrayList<Pe>();
        int mips = 5000;
        // 3. Create PEs and add these into a list.
        //创建处理器,并添加到Pe列表中:为每个主机配置4核CPU 写入Pe id 和 cpu处理速度
        peList.add(new Pe(0, new PeProvisionerSimple(mips))); // need to store Pe id and MIPS Rating
        peList.add(new Pe(1, new PeProvisionerSimple(mips)));
        peList.add(new Pe(2, new PeProvisionerSimple(mips)));
        peList.add(new Pe(3, new PeProvisionerSimple(mips)));
        // 4. Create Host with its id and list of PEs and add them to the list
        // of machines 创建主机,并将其添加至主机列表
        int hostId = 0;
        int ram = 2048; // host memory (MB)
        long storage = 1000000; // host storage
        int bw = 10000;

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

        hostId++;
        hostList.add(
                new Host(
                    hostId,
                    new RamProvisionerSimple(ram),
                    new BwProvisionerSimple(bw),
                    storage,
                    peList,
                    new VmSchedulerTimeShared(peList)
                )
            ); // This is second machine
        hostId++;
        hostList.add(
                new Host(
                    hostId,
                    new RamProvisionerSimple(ram),
                    new BwProvisionerSimple(bw),
                    storage,
                    peList,
                    new VmSchedulerTimeShared(peList)
                )
            ); // This is second machine
        hostId++;
        hostList.add(
                new Host(
                    hostId,
                    new RamProvisionerSimple(ram),
                    new BwProvisionerSimple(bw),
                    storage,
                    peList,
                    new VmSchedulerTimeShared(peList)
                )
            ); // This is second machine

        //创建数据中心特征,它表示了数据中心的资源的静态属性,
        //比如:体系结构,操作系统,主机列表,分配策略,时间或空间共享,时区,价格
        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.001; // the cost of using storage in this
                                        // resource
        double costPerBw = 0.0; // 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 {

            //默认算法:VmAllocationPolicySimple 选择最大剩余PEs的主机分配
            //首次适应算法:VmAllocationPolicyFirstIn 选择最先适配的主机分配
            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
    /**
     * Creates the broker.
     *
     * @return the datacenter broker
     */
    private static DatacenterBroker createBroker() {
        DatacenterBroker broker = null;
        try {
            broker = new DatacenterBroker("Broker");
        } 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 + "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
                        + dft.format(cloudlet.getActualCPUTime()) + indent
                        + indent + dft.format(cloudlet.getExecStartTime())
                        + indent + indent
                        + dft.format(cloudlet.getFinishTime()));
            }
        }
    }

}

  开始仿真模拟时,首先需要创建一个数据中心,然后再数据中心中创建CPU、内存等资源,此时只需要向代理中心注册资源信息,用户就可以使用数据中心的资源进行仿真模拟。在仿真资源分配试验中,其步骤及其各个步骤中的代码如下:
  (1) 初始化Cloudsim包,代码如下:

Int num_user= 1 ; //定义用户数量
Calendar calendar=Calendar.getInstance();
boolean trace_flag=false;
CloudSim.init(num_user, calendar, trace_flag); //初始化CloudSim包

  (2)创建数据中心(Datacenter),如果多次创建那就生成多个数据中心,代码如下所示:

DataCenter datacenter()=createDatacenter("Datacenter_0");

  (3) 创建数据中心代理(Broker),代码如下所示。注:任务到虚拟机的映射是由DatacenterBroker类中的bindCloudletsToVms()函数实现。该函数根据不同的策略来实现任务的映射。

DatacenterBroker broker=createBroker();
Int brokerId=broker.get_id();

  (4) 创建虚拟机,只有提交了虚拟机列表,broker才会发挥作用。代码如下所示:

vmlist=new VirtualMachineList(); //创建虚拟机列表
Vmvm=new Vm(vmid, brokerld, mips, PesNumber, ram, bw, size,
vmm,new CloudletSchedulerTimeShared()); //创建虚拟机
vmlist.add(vm); //加入虚拟机列表
broker.submitVMList(vmlist);//提交虚拟机列表

  (5) 创建云任务,代码如下所示:

cloudletList = new CloudletList();//创建云任务列表
Cloudlet cloudlet=new Cloudlet(id, length, file_size, output_size);
cloudlet.setUserlD(brokerld);
……
cloudletList.add(cloudlet); //将任务加入任务列表
……
broker.submitCloudletList(cloudletList);//向代理提交任务列表

  (6) 执行资源调度算法,完成任务到虚拟机的映射,代码如下所示:

broker. bindCloudletsToVms();

  (7) 启动仿真程序,代码如下所示:

CloudSim.startSimulation();

  (8) 打印仿真结果,代码如下所示:

List<Cloudlet> newList = broker.getCloudletReceivedList();
CloudSim.stopSimulation();
printCloudletList(newList);

  在createDatacenter函数中,我设定了4个主机,为每个主机配置4核CPU。首先写入PEs 的id 和 cpu处理速度。

List<Pe> peList = new ArrayList<Pe>();
int mips = 5000;
//为每个主机配置4核CPU 写入Pe id 和 cpu处理速度
peList.add(new Pe(0, new PeProvisionerSimple(mips)));
peList.add(new Pe(1, new PeProvisionerSimple(mips)));
peList.add(new Pe(2, new PeProvisionerSimple(mips)));
peList.add(new Pe(3, new PeProvisionerSimple(mips)));

  随后,创建四个主机,写入id和PEs列表到主机中。

int hostId = 0;
int ram = 2048; // host memory (MB)
long storage = 1000000; // host storage
int bw = 10000;
hostList.add(
    new Host(
        hostId,
        new RamProvisionerSimple(ram),
        new BwProvisionerSimple(bw),
        storage,
        peList,
        new VmSchedulerTimeShared(peList)
    )
); // This is frist machine
hostId++;
hostList.add(
                new Host(
                    hostId,
                    new RamProvisionerSimple(ram),
                    new BwProvisionerSimple(bw),
                    storage,
                    peList,
                    new VmSchedulerTimeShared(peList)
                )
            ); // This is second machine
hostId++;
...

  创建数据中心的的仓库和属性,这部分的源码我没有修改,具体参见源代码。

VmAllocationPolicySimple

package org.cloudbus.cloudsim.examples;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.cloudbus.cloudsim.Host;
import org.cloudbus.cloudsim.Log;
import org.cloudbus.cloudsim.Vm;
import org.cloudbus.cloudsim.VmAllocationPolicy;
import org.cloudbus.cloudsim.core.CloudSim;
/**
 * VmAllocationPolicySimple is an VmAllocationPolicy that chooses, as the host for a VM, the host
 * with less PEs in use.
 */
//VmAllocationPolicy 抽象类 代表了数据中心主机到虚拟机的供应协议
public class VmAllocationPolicyFirstIn extends VmAllocationPolicy {
    /** The vm table.记录虚拟机被分配到哪台主机 */  
    private Map<String, Host> vmTable;
    /** The used pes.记录虚拟机占用了几个处理器核心 */  
    private Map<String, Integer> usedPes;
    /** The free pes.记录每台主机可用的处理器核心数 */  
    private List<Integer> freePes;
    /**
     * Creates the new VmAllocationPolicySimple object.
     * @param list the list
     * @pre $none
     * @post $none
     */
    public VmAllocationPolicyFirstIn(List<? extends Host> list) {
        //初始化主机列表hostList(继承自父类的成员)  
        super(list);
        //初始化每台主机可用的处理器核心数freePes  
        setFreePes(new ArrayList<Integer>());
        for (Host host : getHostList()) {
            getFreePes().add(host.getNumberOfPes());
        }
        //初始化vmTable和usedPes  
        setVmTable(new HashMap<String, Host>());
        setUsedPes(new HashMap<String, Integer>());
    }
    /**
     * Allocates a host for a given VM.
     * @param vm VM specification
     * @return $true if the host could be allocated; $false otherwise
     * @pre $none
     * @post $none
     */
    @Override
    public boolean allocateHostForVm(Vm vm) {
        int requiredPes = vm.getNumberOfPes();//创建vm所需的处理器核心数
        boolean result = false;
        int tries = 0; //尝试次数
        List<Integer> freePesTmp = new ArrayList<Integer>();
        for (Integer freePes : getFreePes()) {
            freePesTmp.add(freePes);
        }
        //如果当前虚拟机还未创建
        if (!getVmTable().containsKey(vm.getUid())) { // if this vm was not created
            do {// we still trying until we find a host or until we try all of them
                //尝试创建虚拟机直到创建成功或所有的主机都已经尝试过
                int moreFree = Integer.MIN_VALUE;//当前最大可用核心数
                int idx = -1; //当前最大可用核心数对应主机的下标

                //默认算法;找到可用处理器核心数最大的第一台主机
                //TestData:VM所需核数分别为 2 3 3 1
                //正确结果:   剩余资源:2 1 1 3        主机分配ID:0 1 2 3
                for (int i = 0; i < freePesTmp.size(); i++) {
                    if (freePesTmp.get(i) > moreFree) {
                        moreFree = freePesTmp.get(i);
                        idx = i;
                    }
                }

                Host host = getHostList().get(idx);
                result = host.vmCreate(vm);//尝试创建虚拟机
                if (result) { // if vm were succesfully created in the host
                    //更新映射关系及主机可用的处理器核心数
                    getVmTable().put(vm.getUid(), host);
                    getUsedPes().put(vm.getUid(), requiredPes);
                    getFreePes().set(idx, getFreePes().get(idx) - requiredPes);
                    result = true;
                    break;
                } else {//如果创建失败
                    //将当前主机的可用处理器核心数暂时设成最小值,从而排除该主机
                    freePesTmp.set(idx, Integer.MIN_VALUE);
                }
                tries++;
            } while (!result && tries < getFreePes().size());
        }
        System.out.println("配置完成后PEs的剩余情况");
        System.out.println(getFreePes().get(0)+" "+getFreePes().get(1)+" "+getFreePes().get(2)+" "+getFreePes().get(3));

        return result;
    }
    /**
     * Releases the host used by a VM.
     * 
     * @param vm the vm
     * @pre $none
     * @post none
     */
    @Override
    public void deallocateHostForVm(Vm vm) {

        //删除虚拟机相应的映射关系,通过主机销毁虚拟机并更新可用的处理器核心数
        Host host = getVmTable().remove(vm.getUid());
        int idx = getHostList().indexOf(host);
        int pes = getUsedPes().remove(vm.getUid());
        if (host != null) {
            host.vmDestroy(vm);
            getFreePes().set(idx, getFreePes().get(idx) + pes);
        }
    }

...

    //将虚拟机分配给指定的主机
    @Override
    public boolean allocateHostForVm(Vm vm, Host host) {
        if (host.vmCreate(vm)) { //如果虚拟机创建成功,更新vmTable,并返回true  
            getVmTable().put(vm.getUid(), host);
            int requiredPes = vm.getNumberOfPes();
            int idx = getHostList().indexOf(host);
            getUsedPes().put(vm.getUid(), requiredPes);
            getFreePes().set(idx, getFreePes().get(idx) - requiredPes);
            Log.formatLine(
                    "%.2f: VM #" + vm.getId() + " has been allocated to the host #" + host.getId(),
                    CloudSim.clock());
            return true;
        }
        return false;
    }
}

  VmAllocationPolicy类代表了数据中心主机到虚拟机的供应协议。在类刚开始便定义了vm table(记录虚拟机被分配到哪台主机)、used pes(记录虚拟机占用了几个处理器核心)、free pes(记录每台主机可用的处理器核心数),VmAllocationPolicy就是通过PEs处理器核心的个数进行单资源的调度,所以在这里我们只需关心这几个参数。传入Host列表,初始化这几个参数之后,我们便可以开始调度。
  判断当前传入的vm是否已经创建,在逻辑上就是判断VmTable中有没有写入该vm的ID,未创建的话,进行资源分配,并创建虚拟机,以及更新映射关系及主机可用的处理器核心数。如果创建失败,则将当前主机的可用处理器核心数暂时设成最小值,从而排除该主机。具体代码以及详细介绍见上。

四、虚拟机分配

  虚拟机分配指的是,选择满足特定条件(内存、软件环境配置等)的主机创建虚拟机的过程,这个过程由Datacenter对象负责。在云数据中心,将特定应用的虚拟机分配给主机由虚拟机分配控制器VmAllocationPolicy完成,Cloudsim在主机层和虚拟机层都实现了基于时间共享和空间共享的调度策略。用户可以通过继承该类实现自己的分配策略,CloudSim中,作者实现了一种简单的分配策略——VmAllocationPolicySimple。方法allocateHostForVm(Vm vm)是该类的核心,它实现了从主机列表中选择一台主机,并在其上创建虚拟机vm。
  主要实现过程的描述如下:
  1. 记录下所有主机可用的处理器核心数。
  2. 从中选出可用处理器核心数最多的第一台主机,并尝试在其上创建虚拟机。
  3. 如果 2 失败了且还有主机没有尝试过,就排除当前选择的这台主机,重做 2。
  4. 根据虚拟机是否创建成功,返回true或false。

  我们自己写相关算法,执行调度该如何修改代码呢?下面接着叙述。
  虚拟机的初始放置实际上是一个多维向量的装箱问题,装箱问题均是NP-Hard问题,目前针对装箱问题的解法主要为基于贪心算法的启发式算法,例如首次适应算法(First Fit,FF),降序首次适应算法(First Fit Descending,FFD),最佳适应算法(Best Fit,BF)和降序最佳适应启发式算法(Best Fit Descending,BFD)等。

  • (1)首次适应算法:为物品寻找目的箱子时,首先从第一个箱子寻找,如果不满足条件(不能放在箱子),则继续寻找直到找到合适的箱子。在目的箱子中为物品分配所需空间,剩余空间可以继续放置新的物品。如果不能找到合适的箱子,则物品放置失败。
  • (2)降序首次适应算法:首先将箱子按照某种资源(如CPU等)的大小进行降序排序,然后按照首次适应算法查找合适的箱子。如果能找到合适的箱子,则放置物品,更新箱子大小,放置成功,否则放置失败。
  • (3)最佳适应算法:将物品装入箱子时,在所有箱子中查找大于且最接近物品大小的箱子,然后再从该箱子中分配物品所需的空间,余下的空间作为新箱子继续放置其他物品,此时物品放置成功。如果任何箱子都不能放置物品,则放置失败。
  • (4)降序最佳适应算法:在最佳适应算法的基础上进行改进,首先将箱子按照某种资源(如CPU等)的大小进行降序排序,然后执行最佳适应算法查找箱子。若找到合适的箱子,则放置物品并更新箱子的大小,放置成功,否则失败。

默认调度方法

int moreFree = Integer.MIN_VALUE;//当前最大可用核心数
int idx = -1; //当前最大可用核心数对应主机的下标
for (int i = 0; i < freePesTmp.size(); i++) {
    if (freePesTmp.get(i) > moreFree) {
        moreFree = freePesTmp.get(i);
        idx = i;
    }
}

  上面是VmAllocationPolicySimple中的默认算法。即找到可用处理器核心数最大的第一台主机。
  在这里,测试数据为:VM所需核数分别为 2 3 3 1,按照在Example1中定义的VM和Host列表的资源规配置,那么运行出来的正确结果应该是:

  • 0-3号主机中剩余PEs资源:2 1 1 3
  • 0-3号虚拟机的主机分配ID:0 1 2 3

      结果截图:



首次适应算法

int moreFree = Integer.MIN_VALUE;//当前最大可用核心数
int idx = -1; //当前最大可用核心数对应主机的下标
for (int i = 0; i < freePesTmp.size(); i++) {
    if (freePesTmp.get(i) >= requiredPes) {
        idx = i;
        break;
    }
}

  上面是首次适应算法的代码。即按照次序找到符合条件的第一个主机。
  在这里,测试数据为:VM所需核数分别为 2 3 3 1,按照在Example1中定义的VM和Host列表的资源规配置,那么运行出来的正确结果应该是:

  • 0-3号主机中剩余PEs资源:1 1 1 4
  • 0-3号虚拟机的主机分配ID:0 1 2 0

      结果截图:



最佳适应算法

int resource_diff = Integer.MAX_VALUE;//所需资源与目前资源的差值
int idx = -1; //当前最大可用核心数对应主机的下标
for (int i = 0; i < freePesTmp.size(); i++) {
    if (freePesTmp.get(i) >= requiredPes) {
        int r = (freePesTmp.get(i) - requiredPes);//所需资源与目前资源的差值,找出最小的一个
        if(r < resource_diff) {
            resource_diff = r;
            idx = i;
        }
    }
}

  上面是最佳适应算法的代码。即查找出大于且最接近所需PEs大小的主机。
  在这里,测试数据为:VM所需核数分别为 2 3 3 1,按照在Example1中定义的VM和Host列表的资源规配置,那么运行出来的正确结果应该是:

  • 0-3号主机中剩余PEs资源:2 0 1 4
  • 0-3号虚拟机的主机分配ID:0 1 2 1

      结果截图:



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章