用遺傳算法GA改進CloudSim自帶的資源調度策略


首先理解雲計算里,資源調度的含義:

看了很多雲計算資源調度和任務調度方面的論文,發現很多情況下這兩者的意義是相同的,不知道這兩者是同一件事的不同表述還是我沒分清吧,任務調度或者資源調度大概就是講這樣一件事情:

用戶有n個計算任務(Task),{t1,t2,t3,...tm},將這n個任務分配到m個資源(其實就是指虛擬機,Virtual Machine)上,用這m個資源來計算這n個任務(注意,一般n>m,且很多時候n>>m),直到所有任務都計算完成。如何分配使得這n個任務的總的計算時間最少?這里,總的計算時間是指,最后一個計算完成的任務的完成時刻,而不是每個任務的計算時間求和。

關於這個問題的准確的描述,引用王登科 李 忠《基於粒子群優化與蟻群優化的雲計算任務調度算法》的描述:

舉個例子:

 假設某雲計算系統的一台主機上運行了3個虛擬機{VM0,VM1,VM2},它們的計算能力(即單位時間內能夠執行的指令數量,CloudSim里用mips來衡量)分別是{3000,1000,500}.

某用戶有5個計算任務{t0,t1,t2,t3,t4},任務大小(就是要執行的指令數量,CloudSim里用length來表示)分別是{4000,2000,2500,10000,500},提交到cloudsim系統中進行模擬運算。

根據cloudsim默認的調度策略,產生的調度結果是:VM0={t0,t3},VM1={t1,t4},VM2={t2}

由於VM0,VM1,VM2並行執行,互不影響,因此

VM0上的執行時間為:(t0+t3)/VM0 mips=(4000+10000)/3000=4.667,

VM1上的執行時間為:(t1+t4)/VM1 mips=(2000+500)/1000=2.5,

VM2上的執行時間為:t2/VM2 mips=2500/500=5。

因此這種調度方案的總的運行時間為max{4.667,2.5,5}=5。

其中,這種調度方案,可用一個二維表來表示:

 

這個表跟上面的那個X表行和列對調了一下,但意思一樣,注意觀察每一行都只有一個1,表示每個任務只能分配給一個資源(虛擬機)進行計算,但1個資源(虛擬機)可能計算不止一個任務。

如果運用遺傳算法或其他進化算法,需要對每個解(對應這里的每一種調度方案),計算它的適應度值(這里的適應度函數就是每種調度方案對應的任務完成時間),選擇適應度值最好的作為最優,進行下一次迭代。

如何把一種調度方案表示為一個解,如何計算解的適應度值?可以參考:非常好的理解遺傳算法的例子

這里,可以把每一行的二進制數化成一個十進制整數,每個數取值只能取{20,21,22,...,2m-1}中的任意一個,共n個任務,即有n個這樣的數,這就是遺傳算法當中的所謂編碼,即用一種方式來把調度方案表示成解(上面的調度方案可表示為42142,每一位數表示資源的分配結果)。

或者用資源的編號組合來表示調度方案:n個任務,每個任務從[0,m-1]之間的整數任取一個,那么一個調度方案就是一個1*n維的向量,如上例的調度方案可表示為 [0,1,2,0,1]

而把解轉化成調度方案就是所謂解碼。

 

如何把把自己的算法,如遺傳算法運用到Cloudsim中去?最簡單的辦法是調用DatacenterBroker的 bindCloudletToVM(int cloudletId, int vmId),通過遺傳算法的計算結果用代碼動態調用該方法,將任務與資源進行綁定,這種綁定就是任務的調度的體現。

 

如何理解遺傳算法本身,請參考:遺傳算法(Genetic Algorithm) 

說到這,我有點疑問,按照上面的調度表格,每個任務必須要為它分配一個資源,且只能分配一個資源,那調度方案的總個數其實是可以窮舉的,因為n個任務,m個資源,每個任務都有m種選擇,一共就是mn種調度方案。所以最佳調度方案其實是很容易窮舉算出來的,為什么還要用遺傳算法之類的進化算法來算呢?可能是當n足夠大之后,mn這個值太大,調度方案太多,導致窮舉太耗時,才需要這些調度算法吧。

 

 鏈接:基於遺傳算法的資源調度策略的代碼實現

Cloudsim模擬的實例代碼:

public static void RunSimulation(int []taskLength,int taskNum)
    {
        System.out.println("Starting to run simulations...");

        try
        {
            int num_user = 1; // number of cloud users
            Calendar calendar = Calendar.getInstance();
            boolean trace_flag = false;
        
            CloudSim.init(num_user, calendar, trace_flag);

            //下面創建的datacenter是用來運行任務的物理硬件,是必需的,否則不能運行。它被創建之后看似沒有調用,好像沒啥用,其實DataCenter構造函數把它與CloudSim類進行了綁定,所以能夠發揮作用
            @SuppressWarnings("unused")
            Datacenter datacenter0 = createDatacenter("Datacenter_0");

            // #3 step: Create Broker
            DatacenterBroker broker = createBroker();
            int brokerId = broker.getId();
            // #4 step: Create one virtual machine
            vmlist = new ArrayList<Vm>();

            // VM description
            long size = 10000; // image size (MB)
            int ram = 512; // vm memory (MB)
            long bw = 1000;
            int pesNumber = 1; // number of cpus
            String vmm = "Xen"; // VMM name
            
            
            double mips=5000;//mips是虛擬機的cpu處理速度,cloudlet的length/虛擬機mips=任務執行所需時間
            //所有虛擬機的mips之和不能超過datacenter中定義的主機的物理cpu的mips之和,而虛擬cpu的mips的最大值也不能超過物理cpu的最大值,否則虛擬機將創建失敗。
            Vm vm1 = new Vm(0, brokerId, mips, pesNumber, ram, bw, size,
                    vmm, new CloudletSchedulerSpaceShared());
            mips=2500;
            Vm vm2 = new Vm(1, brokerId, mips, pesNumber, ram, bw, size,
                    vmm,new CloudletSchedulerTimeShared());
            mips=2500;
            Vm vm3 = new Vm(2, brokerId, mips, pesNumber, ram, bw, size,
                    vmm,new CloudletSchedulerTimeShared());
            mips=1500;
            Vm vm4 = new Vm(3, brokerId, mips, pesNumber, ram, bw, size,
                    vmm, new CloudletSchedulerSpaceShared());
            mips=1000;
            Vm vm5 = new Vm(4, brokerId, mips, pesNumber, ram, bw, size,
                    vmm, new CloudletSchedulerSpaceShared());

            // add the VMs to the vmList
            vmlist.add(vm1);
            vmlist.add(vm2);
            vmlist.add(vm3);
            vmlist.add(vm4);
            vmlist.add(vm5);

            // submit vm list to the broker
            broker.submitVmList(vmlist);

            // #5 step: Create cloudlets
            cloudletList = new ArrayList<Cloudlet>();

            // Cloudlet properties
            int id = 0;
            pesNumber = 1;
            
            long fileSize = 250;
            long outputSize = 10000000;
            UtilizationModel utilizationModel = new UtilizationModelFull();
            
            for(int i=0;i<taskNum;i++)
            {
                //Cloudlet構造函數的一個參數為任務id,第二個參數為任務長度(指令數量)
                Cloudlet task = new Cloudlet(i, taskLength[i], pesNumber, fileSize,
                        outputSize, utilizationModel, utilizationModel,
                        utilizationModel);
                task.setUserId(brokerId);
                
                cloudletList.add(task);
            }
            
            
            broker.submitCloudletList(cloudletList);
            
            for(int i=0;i<taskNum;i++)
            {
                //下面的兩行代碼用於把任務綁定到指定的虛擬機上,兩行代碼效果是一樣的
                //如果需要用自己實現的算法來進行資源調度,則可以在算法中動態調用DataCenterBroker.bindCloudletToVm()方法或者Cloudlet.setVmId()方法
                //broker.bindCloudletToVm(cloudletList.get(i).getCloudletId(),vm1.getId());
                cloudletList.get(i).setVmId(vm1.getId());
            }
            
            bindAllTaskToSameVM(cloudletList,vm1.getId());
            
            CloudSim.startSimulation();
            
            // Final step: Print results when simulation is over
            List<Cloudlet> newList = broker.getCloudletReceivedList();

            CloudSim.stopSimulation();
        
            for(Vm vm:vmlist)
            {
                System.out.println(String.format("vm id= %s ,mips = %s ",vm.getId(),vm.getMips()));
            }
                       
            printCloudletList(newList);
            System.out.println("CloudSim simulation is finished!");
        } 
        catch (Exception e)
        {
            e.printStackTrace();
            System.out.println("The simulation has been terminated due to an unexpected error");
        }
    }
    
    private static Datacenter createDatacenter(String name)
    {
        List<Host> hostList = new ArrayList<Host>();
        List<Pe> peList = new ArrayList<Pe>();
        
        //創建五個cpu,mips為cpu的處理速度
        int mips = 5000;
        peList.add(new Pe(0, new PeProvisionerSimple(mips))); // need to store Pe id and MIPS Rating
        
        mips = 2500;
        peList.add(new Pe(1, new PeProvisionerSimple(mips))); // need to store
        
        mips = 2500;
        peList.add(new Pe(2, new PeProvisionerSimple(mips))); // need to store
        
        mips = 1500;
        peList.add(new Pe(3, new PeProvisionerSimple(mips))); // need to store
            
        mips = 1000;
        peList.add(new Pe(4, new PeProvisionerSimple(mips))); // need to store
        
        int hostId = 0;
        int ram = 4096; // host memory (MB)
        long storage = 10000000; // host storage
        int bw = 10000;

        hostList.add(new Host(hostId, new RamProvisionerSimple(ram),
                new BwProvisionerSimple(bw), storage, peList,
                new VmSchedulerTimeShared(peList)));
        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.001; // the cost of using bw in this resource
        
        //we are not adding SAN devices by now
        LinkedList<Storage> storageList = new LinkedList<Storage>();

        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;
    }

    private static DatacenterBroker createBroker()
    {

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

    private static void printCloudletList(List<Cloudlet> list)
    {
        int size = list.size();
        Cloudlet cloudlet;

        String indent = "    ";
        System.out.println();
        System.out.println("========== OUTPUT ==========");
        System.out.println("Cloudlet ID" + indent + "STATUS" + indent
                + "Data center ID" + indent + "VM ID" + indent +"CloudletLength"+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.getStatus()== Cloudlet.SUCCESS)
            {
                Log.print("SUCCESS");

                System.out.println(indent +indent + indent + cloudlet.getResourceId()
                        + indent + indent + indent + cloudlet.getVmId()
                        + indent + indent + cloudlet.getCloudletLength()
                        + indent + indent+ indent + indent
                        + dft.format(cloudlet.getActualCPUTime()) + indent
                        + indent + dft.format(cloudlet.getExecStartTime())
                        + indent + indent
                        + dft.format(cloudlet.getFinishTime()));
            }
        }
    }
    

 

本文鏈接:http://www.cnblogs.com/aaronhoo/p/6218024.html

參考資料:

《基於粒子群優化與蟻群優化的雲計算任務調度算法》王登科 李 忠

碩士論文《基於雲計算環境下資源調度算法研究》 鄔海艷

http://blog.csdn.net/b2b160/article/details/4680853/

http://blog.chinaunix.net/uid-27105712-id-3886077.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM