CloudSim3.0.3power编程examples及辅助类解析

来源:互联网 发布:跟兄弟连学php 电子书 编辑:程序博客网 时间:2024/06/07 17:44

CloudSim3.0.3power编程examples及辅助类解析

power编程依赖的底层主要类(PowerDataCenter、PowerDCBroker、调度策略类等等)都是org.cloudbus.cloudsim.power包中,这些类在之前的文章中已经介绍:

Cloudsim 3.0.3中Power系列类的解析——PowerDataCenter和PowerDCBroker(2017-07-17 16:36)

Cloudsim 3.0.3中Power系列类的解析——PowerHost, PowerVM, PowerModel(2017-07-18 09:57)

Cloudsim 3.0.3中VM调度策略系列类解析(无迁移的策略)(2017-07-18 15:06)

Cloudsim 3.0.3中VM调度策略系列类解析(带迁移的策略)(2017-07-18 17:12)

等等

CloudSim3.0.3与power包相关的样例在org.cloudbus.cloudsim.examples.power.random/planetlab中,基本辅助类在org.cloudbus.cloudsim.examples.power中,样例特定的辅助类则与样例存放在一起。

1、基本辅助类

位置:org.cloudbus.cloudsim.examples.power,用于辅助power examples的编写,功能主要包括定义所有常量(如VM类型、host类型、任务类型、调度间隔schedulingInterval等)、创建数据中心、VM等各实验对象和初始化并启动模拟等等。

1.1 org.cloudbus.cloudsim.examples.power.Constants.java

定义了power仿真需要用到的各种常量,重要常量包括:

        public final static double SCHEDULING_INTERVAL = 300;  //调度间隔,在创建DC时会传入,数据中心在无事件可处理时,会发出delay=SCHEDULING_INTERVAL的事件以将clock向前推演一个间隔。另外,从example代码中看,300秒同时是planetlab.workload负载数据的间隔。
public final static double SIMULATION_LIMIT = 24 * 60 * 60; //仿真模拟时间上限=1天

// length: 2500 mips * 1 day
public final static int CLOUDLET_LENGTH= 2500 * (int) SIMULATION_LIMIT; //云任务的指令长度
public final static int CLOUDLET_PES= 1; //云任务的PE需求

        //定义了4种虚拟机,均为单核
public final static int VM_TYPES= 4;
public final static int[] VM_MIPS= { 2500, 2000, 1000, 500 };
public final static int[] VM_PES= { 1, 1, 1, 1 };
public final static int[] VM_RAM= { 870,  1740, 1740, 613 };
public final static int VM_BW= 100000; // 100 Mbit/s
public final static int VM_SIZE= 2500; // 2.5 GB

// 定义了2种服务器
public final static int HOST_TYPES= 2;
public final static int[] HOST_MIPS= { 1860, 2660 };
public final static int[] HOST_PES= { 2, 2 };
public final static int[] HOST_RAM= { 4096, 4096 };
public final static int HOST_BW= 1000000; // 1 Gbit/s
public final static int HOST_STORAGE = 1000000; // 1 GB

        //2种服务器对应的能耗模型

        //每个能耗模型就是一个11元素(0%-100%)的数组
public final static PowerModel[] HOST_POWER = {
new PowerModelSpecPowerHpProLiantMl110G4Xeon3040(),
new PowerModelSpecPowerHpProLiantMl110G5Xeon3075()
};

1.2 org.cloudbus.cloudsim.examples.power.Helper.java

主要封装了创建Broker、DataCenter、主机、VM方法逻辑(Cloudlet不在此创建),用于创建数据中心的最基本组件和底层逻辑,主要方法如下:

public static List<PowerHost> createHostList(int hostsNumber) {
...
//创建主机集合,只需指定数量,其它信息由Constants内指定,其中主机类型是那2种类型循环创建,主机上的VM是timeShared} 
public static Datacenter createDatacenter(String name,Class<? extends Datacenter> datacenterClass,List<PowerHost> hostList,VmAllocationPolicy vmAllocationPolicy) {
...
//创建数据中心,需要指定datacenterClass(在power包中,用到的基本是PowerDataCenter类,譬如RunnerAbstract中调用createDataCenter就传入的它),
//还需要指定vmAllocationPolicy,即虚拟机调度策略类(在系列文章中介绍过),vmAllocationPolicy内部包含了vmSelectionPolicy。
...
}

public static DatacenterBroker createBroker() {
...
//创建Broker
} 
public static List<Vm> createVmList(int brokerId, int vmsNumber) {
...
// 指定要创建的VM数量,根据Constants.java内指定的4种VM类型类创建VM。
}
public static void printResults(PowerDatacenter datacenter,List<Vm> vms,double lastClock,String experimentName,boolean outputInCsv,String outputFolder) {
...
// 这是打印函数,根据传入的PowerDC对象和主机列表,统计各种各样的数据(e.g., 总能耗DC.getPower()、MigrationCount、slaTimePerActiveHost等等)
// 同时会输出到参数指定的outputFolder中的文件(不存在则创建)
}

1.3 org.cloudbus.cloudsim.examples.power.RunnerAbstract.java

在更高一层封装了整个实验初始化代码,将power仿真程序中整个逻辑(从init、创建DC到提交云任务并开始仿真、最后到结束仿真)都封装在了构造函数里,其中构造函数里调用init()方法完成DCBroker、host集合、VM集合和Cloudlet集合的初始化,然后根据字符串解析出所指定的VmAllocationPolicy对象,再调用start()方法创建数据中心(用Helper提供的函数)。不过,基本辅助类RunnerAbstract是抽象类,start()方法是完整可用的(事实上辅助子类直接继承该方法),但init()方法为空,需要继承的子辅助类来实现,这是因为不同样例需要定义的Cloudlet集合不相同。
关键方法解析:

1.3 org.cloudbus.cloudsim.examples.power.RunnerAbstract.java

public RunnerAbstract(boolean enableOutput,boolean outputToFile,String inputFolder,String outputFolder,String workload,String vmAllocationPolicy,String vmSelectionPolicy,String parameter) {
// 构造函数,整个仿真逻辑都封装在了构造函数里,先调用initLogOutput()方法初始化输出目录和文件(其中文件命名与workload、policy等相关),再调用init()方法
// 初始化DCBroker、host集合、VM集合和Cloudlet集合,最后解析字符串获得vmAllocationPolicy对象和vmSelectionPolicy对象并传入start()方法开始仿真。
// 所以该构造函数(准确的说是其子类构造函数)的调用就代表初始化并开始仿真了。
...}

protected abstract void init(String inputFolder);
// init()在RunnerAbstract中是抽象函数,没有实现,因为Cloudlet的定义因样例而异。
protected void start(String experimentName, String outputFolder, VmAllocationPolicy vmAllocationPolicy) {
// 首先根据hostlist成员和vmAllocationPolicy创建出数据中心(指定为PowerDataCenter类),使能VM迁移(datacenter.setDisableMigrations(false)),
// 然后通过broker提交VM列表和Cloudlet列表,开始仿真,接收云任务执行返回列表后调用Helper的printResults()方法输出统计信息。
...}


2、样例相关的辅助类

与样例存放在一起,其中planetlab包包含使用planetlab负载数据(一大批数据文件)的样例,random包则是使用随机的负载数据。两个包里面的样例的逻辑基本是一样的,本节以random包中的辅助类和样例为例。

2.1 RandomConstants.java: 
定义了3个常量:
  public final static int NUMBER_OF_VMS = 50;  public final static int NUMBER_OF_HOSTS = 50;  public final static long CLOUDLET_UTILIZATION_SEED = 1;
// RandomConstants.java是power包中的Constants.java的补充,补充的内容就是VM数、HOST数
2.2 RandomHelper.java:
//是对power包中的Helper.java的补充,补充了创建Cloudlet集合的函数如下:

public static List<Cloudlet> createCloudletList(int brokerId, int cloudletsNumber)
{
...
//该方法根据指定的cloudlet数量、power包Constants.java中定义的任务属性(指令长度、核数)来创建任务集合,另外任务的CPU负载模型采用
//UtilizationModelStochastic类,内存和带宽用的utilizationModelNull。
...
}
2.3 RandomRunner.java
继承:power包的RunnerAbstract
重要函数:
public RandomRunner(...){
...
//通过super()调用父类的构造函数,封装整个初始化和模拟程序逻辑。
}
@Overrideprotected void init(String inputFolder) {
  ...
  CloudSim.init(1, Calendar.getInstance(), false);//初始化
  broker = Helper.createBroker();//调用Helper的方法创建Broker    cloudletList = RandomHelper.createCloudletList(brokerId, RandomConstants.NUMBER_OF_VMS);//调用RandomHelper的方法创建Cloudlet集合
  vmList = Helper.createVmList(brokerId, cloudletList.size());//调用Helper的方法创建VM集合
  hostList = Helper.createHostList(RandomConstants.NUMBER_OF_HOSTS);//调用Helper的方法创建HOST集合
  ...
}
init()方法实现了父类抽象方法(父类RunnerAbstract)没有实现,完成DCBroker、cloudlet集合、VM集合和HOST集合的创建。

3、程序样例
    有了上述的power包相关基本辅助类和特定样例辅助类,power仿真样例的代码就十分简洁了。
    下面以org.cloudbus.cloudsim.examples.power.random包中的两个样例为例,一个是采用简单调度策略(PowerVmAllocationPolicySimple,系列文章中讲过,是无迁移的
First-Fit)的程序样例NonPowerAware.java,以及一个基于阈值选择迁出VM、基于负载相关性进行放置的程序样例ThrMc.java(Thr指基于阈值的vmSelectionPolicy,Mc指基
于Max correlation的放置策略,二者组合为一个总的vmAllocationPolicy来管理DC)。


3.1、NonPowerAware.java
该样例仿真一个采用简单FF调度策略的数据中心,它没有借助RunnerAbstract及其,而是直接调用power包的辅助类(Helper和Constants)的方法、Random包的样例辅助类完成的各类对象创建,所以代码比较长。

public class NonPowerAware {/** * Creates main() to run this example. *  * @param args the args * @throws IOException */public static void main(String[] args) throws IOException {String experimentName = "random_npa";String outputFolder = "output";//允许VM调度Log.setDisabled(!Constants.ENABLE_OUTPUT);Log.printLine("Starting " + experimentName);try {CloudSim.init(1, Calendar.getInstance(), false);//用Helper的方法创建BrokerDatacenterBroker broker = Helper.createBroker();int brokerId = broker.getId();//用RandomHelper的方法创建任务列表List<Cloudlet> cloudletList = RandomHelper.createCloudletList(brokerId,RandomConstants.NUMBER_OF_VMS);
//用Helper的方法创建VM集合List<Vm> vmList = Helper.createVmList(brokerId, cloudletList.size());
//用Helper的方法创建host集合
List<PowerHost> hostList = Helper.createHostList(RandomConstants.NUMBER_OF_HOSTS);
//用Helper的方法创建数据中心,并且该样例指定为PowerDatacenterNonPowerAware,VM调度策略使用PowerVmAllocationPolicySimple
//即First-Fit
PowerDatacenterNonPowerAware datacenter = (PowerDatacenterNonPowerAware) Helper.createDatacenter("Datacenter",PowerDatacenterNonPowerAware.class,hostList,newPowerVmAllocationPolicySimple(hostList));datacenter.setDisableMigrations(true);broker.submitVmList(vmList);broker.submitCloudletList(cloudletList);CloudSim.terminateSimulation(Constants.SIMULATION_LIMIT);double lastClock = CloudSim.startSimulation();List<Cloudlet> newList = broker.getCloudletReceivedList();Log.printLine("Received " + newList.size() + " cloudlets");CloudSim.stopSimulation();Helper.printResults(datacenter,vmList,lastClock,experimentName,Constants.OUTPUT_CSV,outputFolder);} catch (Exception e) {e.printStackTrace();Log.printLine("The simulation has been terminated due to an unexpected error");System.exit(0);}Log.printLine("Finished " + experimentName);}}

该样例调度策略选择的是PowerVmAllocationPolicySimple,是一种无迁移的简单FF;另外,它没有使用RunnerAbstract及其子类提供的方法来创建DC,是因为它创建的是PowerDatacenterNonPowerAware对象(而非PowerDatacenter)。
查看代码,我发现PowerDatacenterNonPowerAware是继承PowerDatacenter的,并且唯一@override的方法是updateCloudletProcessing() ——一个负责输出主机、DC功耗/能耗等信息、调用各主机实例的updateVmsProcessing()方法并根据最快出现的状态变化时刻发出下一个DC事件。虽然实现不尽相同,PowerDatacenterNonPowerAware中updateCloudletProcessing()相比其父类PowerDatacenter逻辑上基本没什么不同,主要区别在于前者是先打印当前集群功耗/能耗信息,再进行状态更新,最后VM调度;而其父类则是先(调用updateCloudetProcessingWithoutSchedulingFutureEventsForce)完成状态更新和信息打印,最后VM调度。

编写自定义VM掉策略的测试样例时,如果想减少封装使代码更直观,那么NonPowerAware.java是不错的参考。



3.2、ThrMc.java
该样例仿真一个采用复杂VM策略(基于阈值选择迁出VM、基于负载相关性进行放置)的PowerDC,使用了特定辅助类RandomRunner来实现全部创建和模拟启动工作,所以代码很简洁。

public class ThrMc {public static void main(String[] args) throws IOException {boolean enableOutput = true;boolean outputToFile = false;String inputFolder = "";String outputFolder = "";String workload = "random"; // Random workload,对于plannetlab的样例,这里就要指定负载文件名String vmAllocationPolicy = "thr"; // Static Threshold (THR) VM allocation policyString vmSelectionPolicy = "mc"; // Maximum Correlation (MC) VM selection policyString parameter = "0.8"; // the static utilization threshold
// 辅助类RandomRunner的构造函数包含了所有逻辑,上面代码指定的各字符串会被解析并用于PowerDatacenter的配置和创建new RandomRunner(enableOutput,outputToFile,inputFolder,outputFolder,workload,vmAllocationPolicy,vmSelectionPolicy,parameter);}}

在RandomRunner的构造函数中,vmSelectionPolicy = "mc"会被解析为PowerVmSelectionPolicyMaximumCorrelation(基于最大相关性的迁出VM选择),vmAllocationPolicy = "thr"会被解析成为PowerVmAllocationPolicyMigrationStaticThreshold(基于静态阈值的VM放置)。前者创建后作为参数传给后者的构造函数成为后者成员(毕竟VMSelection是整个Allocation或者说VMScheduling的一部分),因为带迁移的VM调度策略的抽象类PowerVmAllocationPolicyMigrationAbstract有成员:private PowerVmSelectionPolicy vmSelectionPolicy; (详见系列文章Cloudsim 3.0.3中VM调度策略系列类解析(带迁移的策略)(2017-07-18 17:12))。





原创粉丝点击