云计算框架下基于信用的调度算法分析

package org.cloudbus.cloudsim.examples;

/*
程序说明:整个项目利用Cloudsim3.0的云计算仿真框架进行云任务的仿真。
该程序总共有两个类,一个为fuxian5.java,一个为Bee.java,其中在fuxian5.java中创建了多个实验需要用到的全局变量,方便在下边的云任务输出函数中进行调用。
由于vm列表和云任务列表都设置为全局变量,因此,赋值时,需要单独创建对应的函数进行传参,并返回一个值,否则在其他函数中调用该值时将为0。
我们先在主函数中调用虚拟机和云任务列表的创建函数,并赋值,以此来方便其他函数中对这两个列表进行调用。为了使实验更好的进行,我们还对一些虚拟机和云任务的参数进行随机数的产生,进而会生成不同的虚拟机序列和云任务序列,并上传至数据中心。
我们在CreateVmholdIndex()函数中调用Bee类中求出来的最优解以及相关系数,并利用这些值经过计算来返回特定虚拟机的序列号,方便之后的调用。
在createDatacenter()函数中,在进行主机列表,数据中心列表的创建后,调用了costs数组,用来计算云任务的成本值。
在printCloudletList()函数中,先定义了信用值,云任务长度,信用度优先级,存放负载等数组,通过设置各种循环并调用其它函数进行赋值。
通过相应的credit值的设置,通过相关公式来计算实验需要得出的分配任务的长度、任务的优先级、成本和任务的截止日期等参数,并利用这些参数
进而实现将蜜蜂优化算法用于负载平衡,并利用蜂蜜算法的负载对可信任务进行调度的目的。
这里只给出fuxian5.java类,至于蜜蜂优化算法这里不做描述。
 */

import java.text.DecimalFormat;
import java.util.*;

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.lists.CloudletList;
import org.cloudbus.cloudsim.lists.PeList;
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 fuxian5 {
    //创建云任务列表
    public static List<Cloudlet> cloudletList;
    //创建虚拟机列表
    public static List<Vm> vmlist;
    //定义信任值
    public static int credit;
    //每个云任务的总成本
    public static double costtotal;
    //创建Bee类的对象,方便下面的调用
    static Bee b2=new Bee();
    //用来存储特定虚拟机的序列号
    public static int VmholdIndex;
    //用来存储特定虚拟机的存储容量
    public static double Vmhold;
    //特定虚拟机的处理时间
    public static double processtime;

    /**
     * @param userId the args
     *               创建虚拟机的函数,方便全局传参
     */
    private static List<Vm> createVM(int userId, int vms) {
        //创建一个容器用于存储虚拟机,放入列表中
        LinkedList<Vm> list = new LinkedList<Vm>();
        //设置虚拟机的mips为随机数
        int [] mips1=new int[vms];
        for(int j=0;j<vms;j++){
            mips1[j]=(int)(Math.random()*999+500);
        }
        //VM 参数
        //设置大小
        long size = 10000;
        //设置虚拟机内存
        int ram = 512;
        long bw = 1000;
        //cpu数量
        int pesNumber = 1;
        //虚拟机的名字
        String vmm = "Xen";
        //创建Vms
        Vm[] vm = new Vm[vms];

        for(int i=0;i<vms;i++){
            vm[i] = new Vm(i, userId, mips1[i], pesNumber, ram, bw, size, vmm, new CloudletSchedulerTimeShared());
          //为云任务创建一个空间的时间策略
            list.add(vm[i]);
        }
        return list;
    }


    //创建云任务序列的函数
    private static List<Cloudlet> createCloudlet(int userId, int cloudlets){
        // 创建一个容器用来存储云任务列表
        LinkedList<Cloudlet> list = new LinkedList<Cloudlet>();

        //设置循环用于创建云任务长度的随机数
        int [] length1=new int[cloudlets];
        for(int j=0;j<cloudlets;j++){
            length1[j]=(int)(Math.random()*999+1);
        }

        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(i, length1[i], pesNumber, fileSize, outputSize, utilizationModel, utilizationModel, utilizationModel);
            cloudlet[i].setUserId(userId);
            list.add(cloudlet[i]);
        }

        return list;
    }

    public static void main(String[] args) {
        // Bee1 x=new Bee1();

        Log.printLine("Starting  云计算仿真实验...");

        try {
            //初始化Cloudsim的包
            //云任务使用者的数量
            int num_user = 1;
            Calendar calendar = Calendar.getInstance();
            // mean trace events
            boolean trace_flag = false;

            // 初始化Cloudsim
            CloudSim.init(num_user, calendar, trace_flag);

            //创建数据中心的对象,用于仿真
            Datacenter datacenter0 = createDatacenter("Datacenter_0");

            Datacenter datacenter1 = createDatacenter("Datacenter_1");

            // 创建 Broker
            DatacenterBroker broker = createBroker();
            int brokerId = broker.getId();

            //创建20台虚拟机
            vmlist = createVM(brokerId,20);
            // 创建40个云任务
            cloudletList = createCloudlet(brokerId,40);
            broker.submitVmList(vmlist);

            //递交云任务到broker中
            broker.submitCloudletList(cloudletList);

            //  Starts the simulation
            CloudSim.startSimulation();
            List<Cloudlet> newList = broker.getCloudletReceivedList();
            CloudSim.stopSimulation();
            printCloudletList(newList);
            datacenter0.printDebts();
            datacenter1.printDebts();

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

    }

    public static int CreateVmholdIndex(int vmholdIndex){
        int iter=0;
        int j=0;
        b2.initial();      /*初始化所有食物源 ,这里为云任务的参数*/
        b2.MemorizeBestSource();       /*记录最优解*/
        for (iter=0;iter<b2.maxCycle;iter++)
        {
            b2.SendEmployedBees();     /*雇佣蜂阶段*/
            b2.CalculateProbabilities();       /*计算食物源适应度*/
            b2.SendOnlookerBees();     /*观察蜂阶段*/
            //bee.MemorizeBestSource();       /*记录最优解*/
            b2.SendScoutBees();        /*侦查蜂阶段*/
        }

        for(j=0;j<b2.D;j++)        /*循环打印4个最优解的参数*/
        {
            System.out.println("利用蜜蜂优化算法得出的影响最优解计算的参数["+(j+1)+"]:"+b2.GlobalParams[j]);
        }
        VmholdIndex=(int)b2.GlobalMin;
        if(VmholdIndex>20){
            VmholdIndex= VmholdIndex%20;
            //由于虚拟机数量为20,所以这里我们必须取余,不然会超出虚拟机列表的长度
        }//这里利用人工蜂群算法算出的最优解来求解特定的虚拟机的下角标
        return VmholdIndex;
    }

   //创建数据中心函数
    public static Datacenter createDatacenter(String name) {
        DatacenterBroker broker = createBroker();
        int brokerId = broker.getId();
        //创建一个主机列表进行存储
        List<Host> hostList = new ArrayList<Host>();
        //创建一个云任务列表
        List<Cloudlet>cloudletList=new ArrayList<Cloudlet>();
        //创建虚拟机列表
        List<Vm>vmList=new ArrayList<Vm>();
        //这些为创建上述列表的过程中将会用到的参数
        int mips = 1000;
        long size = 10000;
        int ram = 512;
        long bw = 1000;
        String vmm = "Xen";
        int id = 0;
        int vmid = 0;
        long length = 400000;
        long fileSize = 300;
        long outputSize = 300;
        int pesNumber = 1;
        UtilizationModel utilizationModel = new UtilizationModelFull();
        //给云任务列表传参
        Cloudlet cloudlet = new Cloudlet(id, length, pesNumber, fileSize, outputSize, utilizationModel, utilizationModel, utilizationModel);
        cloudlet.setVmId(vmid);
        // 添加云任务到云任务列表中
        cloudletList.add(cloudlet);
        //创建用于存放每个任务成本的数组
        double [] costs=new double[cloudletList.size()];

        Vm vm = new Vm(vmid, brokerId, mips, pesNumber, ram, bw, size, vmm, new CloudletSchedulerTimeShared());

        // 添加虚拟机到虚拟机列表中
        vmList.add(vm);

        //创建PE列表
        List<Pe> peList1 = new ArrayList<Pe>();
        //创建PE并放入列表中
        //需要一个存储pe的id和MIPS比率
        peList1.add(new Pe(0, new PeProvisionerSimple(mips)));

        peList1.add(new Pe(1, new PeProvisionerSimple(mips)));
        peList1.add(new Pe(2, new PeProvisionerSimple(mips)));
        peList1.add(new Pe(3, new PeProvisionerSimple(mips)));

        List<Pe> peList2 = new ArrayList<Pe>();

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

        //创建主机时,给相关参数赋值
        int hostId = 0;
        //主机内存
        int ram1 = 2048;
        //主机的存储空间
        long storage = 1000000;
        int bw1 = 10000;

        hostList.add(
                new Host(
                        hostId,
                        new RamProvisionerSimple(ram1),
                        new BwProvisionerSimple(bw1),
                        storage,
                        peList1,
                        new VmSchedulerTimeShared(peList1)
                )
        );//第一台主机
        hostId++;

        hostList.add(
                new Host(
                        hostId,
                        new RamProvisionerSimple(ram),
                        new BwProvisionerSimple(bw),
                        storage,
                        peList2,
                        new VmSchedulerTimeShared(peList2)
                )
        ); // 第二台主机


        //系统框架
        String arch = "x86";
        //操作系统名称
        String os = "Linux";
        double time_zone = 10.0;
        //在这个资源中进程在使用时的消耗
        double cost = 3.0;
        //在这个资源中使用内存的消耗
        double costPerMem = 0.05;
        //存储空间的消耗
        double costPerStorage = 0.001;
        // 在这个资源中Bw的消耗
        double costPerBw = 0.0;
        LinkedList<Storage> storageList = new LinkedList<Storage>();
        DatacenterCharacteristics characteristics = new DatacenterCharacteristics(
                arch, os, vmm, hostList, time_zone, cost, costPerMem,
                costPerStorage, costPerBw);
        //该循环用于获取云任务的成本
        for(int o=0;o<cloudletList.size();o++){
            costs[o]=characteristics.getCostPerMem()*vmList.get(o).getRam()+ characteristics.getCostPerStorage()*vmList.get(o).getSize();
        }

        //创建一个Power数据中心
        Datacenter datacenter = null;
        try {
            datacenter = new Datacenter(name, characteristics, new VmAllocationPolicySimple(hostList), storageList, 0);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return datacenter;
    }

    //创建broker
    public static DatacenterBroker createBroker() {
        DatacenterBroker broker = null;
        try {
            broker = new DatacenterBroker("Broker");
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return broker;
    }

    //创建云任务列表的函数
    public 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("###.##");

        int k;//g为MIPS最大值的虚拟机编码,k为中间替换参数,这里和上边一样用冒泡排序
        int [] b =new int[size];//b数组用于存放每个任务的长度
        int [] c =new int[size];//最终存放每个任务的信用值
        int [] q =new int[size];//q数组为经过计算后的每个任务的长度
        double [] d =new double[size]; //创建信用度优先级的数组
        int [] e =new int[vmlist.size()];//创建vm的数组,用来存放数组列表中所有的mips长度
        double [] deadline=new double[size]; //创建用来放置Deadline_task的数组
        double [] Load=new double[size];//用来存放虚拟机中负载的数组
        double cost=0.8;//确定成本系数
        double [] vmholds=new double[vmlist.size()];//创建用来存储各个虚拟机总容量的数组
        double vmaverrage;//虚拟机的标准差
        int [] a=new int[vmlist.size()];//该数组用于存放存储过载虚拟机的序列号,等价于将过载的虚拟机放入过载序列中
        for (int i = 0; i < size; i++) {
            cloudlet = list.get(i);

            //用于存放每个任务的长度
            b[i]= (int) list.get(i).getCloudletLength();
            //int [] c =new int[size];//用于存放每个调度任务的credit值
            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()));
            }
        }

        for (int f=0;f< vmlist.size();f++){
            e[f]=(int) vmlist.get(f).getMips();
            //该循环用于获取虚拟机列表中各个元素的MIPS长度
        }

        //通过冒泡法将MIPS最大的虚拟机置换到最前边,即MIPS长度最大的虚拟机的数组编码为0
        for (int h=0;h< vmlist.size();h++){
            if(e[h]<e[h++]){
                k=e[h];
                e[h]=e[h++];
                e[h++]=k;
            }
        }
        double total=0.0;
        for(int j=0;j<size;j++){

            int t;//作为下边交换的中间值
            int m=0,n;//m为任务列表中每个任务的长度,n为平均值
            m=(int) (m+b[j]);
            n=m/(j+1);
            q[j]=(int)Math.abs(n-b[j]+1);//这里调用Math里面的绝对值函数

            //均为实验中计算信用值的参数
            int a1,a2,a3,a4;
            //该循环用来求出所有任务的长度的最大值
            for(int y=1;y<size;y++){
                if (b[y]>b[j]){
                    t=b[y];
                    b[y]=b[j];
                    b[j]=t;
                }//这块需要注意,要放在大循环的外边,因为必须等待云任务列表中所有的云任务被分配完毕后,才能调用
            }
            a1=b[0]/5;
            a2=b[0]/4;
            a3=a2+a1;
            a4=a3+a2;

            //设置if语句用来设置信用值
            if (q[j] <= a1 || a1 == 1) {
                credit = 5;
            } else if (a1 < q[j] && q[j] <= a2) {
                credit = 4;
            } else if (a2 < q[j] && q[j] <= a3) {
                credit = 3;
            } else if (a3 < q[j] && q[j] <= a4) {
                credit = 2;
            } else {
                credit = 1;
            }
            //最终存放每个任务的信用值
            c[j]=credit;

            //d[j]为每个任务的优先级的权重,方便之后的调用
            d[j]=c[j]*1000/q[j];//这里的可分除因素我们选用上边的q[i]

            //用来放置Deadline_task
            deadline[j]= (c[j]*d[j]/e[0]);
            //计算出所有云任务的总成本costs[i]
            costtotal=c[j]*d[j]*deadline[j]*cost;
            //设置if语句,由于虚拟机在创建时的个数为20,云任务为40,则输出20个虚拟机中的负载的大小
            if(j<20) {
                Load[j] = vmlist.get(j).getSize() * b[j] / (vmlist.get(j).getMips()*10);
                Log.printLine(" ");
                Log.printLine("虚拟机"+j+"负载量为:"+Load[j]);
            }

            //这里创建Bee类的对象,获取Bee类的参数
            b2.NP= vmlist.size();
            b2.FoodNumber= list.size();
            for (int i=0;i< b2.FoodNumber;i++){
                b2.Credit[i]=c[i];
                b2.Cost[i]=cost;
                b2.deadline[i]=deadline[i];
                b2.length[i]=list.size();
            }
            Log.printLine("");
            Log.printLine("云任务"+j+"的长度为:"+q[j]);
            Log.printLine("云任务"+j+"的优先级权重为:"+d[j]);
            Log.printLine("云任务"+j+"的成本为:"+costtotal);
            total=total+costtotal;
        }

        Log.printLine("云任务的总成本数:"+total);
        //计算特定虚拟机的序列号
        VmholdIndex=CreateVmholdIndex((int)b2.GlobalMin);
        Log.printLine("特定虚拟机的序列号为:"+VmholdIndex);
        //计算特定虚拟机的总容量
        Vmhold=vmlist.size()*vmlist.get(VmholdIndex).getMips()+vmlist.get(VmholdIndex).getBw();
        Log.printLine("特定虚拟机的总容量为:"+Vmhold);
        Log.printLine("特定虚拟机的负荷为:"+Load[VmholdIndex]);
        //计算该虚拟机处理的时间
        processtime=Load[VmholdIndex]/Vmhold;
        Log.printLine("处理时间:"+processtime+"ms");
        double o=0;
        double y;
        //设置循环,用来存储所有虚拟机的容量,方便计算虚拟机的标准差
        for(int p=0;p<vmlist.size();p++){
            vmholds[p]=vmlist.size()*vmlist.get(p).getMips()+vmlist.get(p).getBw();
            //o用来存放所有虚拟机的总容量
            o=o+vmholds[p];
        }
        //虚拟机容量的平均值
        y=o/vmlist.size();
        double fangcha=0;
        for(int n=0;n<vmlist.size();n++){
            fangcha=fangcha+(vmholds[n]-y)*(vmholds[n]-y);
        }
        //这里获取虚拟机的标准差
        vmaverrage=Math.sqrt(fangcha);
        Log.printLine("虚拟机容量的标准差"+vmaverrage);
        //这里设置循环,存放超载的虚拟机的序列号
        for(int f=0;f<vmlist.size();f++){
            if(vmholds[f]<vmaverrage){
                a[f]=f;
            }
        }
        List l=new java.util.ArrayList();
        //该循环进行数组中相同数的过滤
        for(int t=0;t<a.length;t++){
            if(!l.contains(a[t]))
                l.add(a[t]);
        }
        Log.printLine("20台虚拟机中超负载虚拟机的序号:(注意:这里由于输出的为过载的虚拟机序列号,根据实验要求将会停止仿真)");
        //设置循环,将上述数组中过滤后的数值给输出出来
        for(Iterator ll = l.iterator(); ll.hasNext();){
            Log.printLine(ll.next());
            CloudSim.stopSimulation();
        }
        Log.printLine("    ");
        Log.printLine("仿真完毕!!!");
    }

}












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值