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

      結果截圖:



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