前言
先前的例子在代码中指定数据中心、主机、虚拟机的参数,如:ram 、bw 、storage 、mips 、PEs 等,非常混乱。通过改进,实现从XML配置文件读取数据来创建,实现数据与逻辑分类,使之更加直观。
配置文件
通过抽象,将一个数据中心(datacenter)描述成如下配置文件。
datacenters.xml
<?xml version="1.0"?>
<datacenters>
<datacenter arch="x86" os="Linux" >
<hosts>
<host>
<core>4</core>
<mips>8000</mips>
<ram>1600</ram>
<storage>20000</storage>
<VMs>
<VM>
<core>1</core>
<mips>1000</mips>
<ram>400</ram>
<storage>2000</storage>
</VM>
<VM>
<core>1</core>
<mips>1000</mips>
<ram>400</ram>
<storage>2000</storage>
</VM>
<VM>
<core>2</core>
<mips>5000</mips>
<ram>800</ram>
<storage>4000</storage>
</VM>
</VMs>
</host>
</hosts>
</datacenter>
</datacenters>
关于主机的带宽参数,虚拟机的CPU调度策略等,可以写到另外的配置文件中。
DatacenterParameters.java
public class DatacenterParameters {
public static int WAN_BANDWIDTH = 300;
public static String CPU_ALLOCATION_POLICY = "SPACE_SHARED";
}
解析数据
- 同一数据中心的主机(host)分配相同的带宽,也即配置文件中的
WAN_BANDWIDTH 。 - 同一台主机上的虚拟机上均分带宽,也即:
long vmBandwidth = bandwidth / vmNodeList.getLength(); 。 - 在创建虚拟机时将虚拟机绑定到所属的主机上。
public class DatacentersManager {
private final List<DatacenterSimple> datacentersList;
private final List<Vm> vmList;
private final CloudSim simulation;
public DatacentersManager(CloudSim simulation) {
this.simulation = simulation;
this.datacentersList = new ArrayList<>();
this.vmList = new ArrayList<>();
}
public void createDataCenters(String file) throws Exception {
File serversFile = new File(file);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(serversFile);
NodeList datacenterList = doc.getElementsByTagName("datacenter");
for (int i = 0; i < datacenterList.getLength(); i++) {
Node datacenterNode = datacenterList.item(i);
Element datacenterElement = (Element) datacenterNode;
List<Host> hostList = createHosts(datacenterElement);
datacentersList.add(new DatacenterSimple(simulation, hostList));
}
}
private List<Host> createHosts(Element datacenterElement) {
List<Host> hostList = new ArrayList<>();
NodeList hostNodeList = datacenterElement.getElementsByTagName("host");
for (int j = 0; j < hostNodeList.getLength(); j++) {
Node hostNode = hostNodeList.item(j);
Element hostElement = (Element) hostNode;
int numOfCores = Integer.parseInt(hostElement.getElementsByTagName("core").item(0).getTextContent());
double mips = Double.parseDouble(hostElement.getElementsByTagName("mips").item(0).getTextContent());
long storage = Long.parseLong(hostElement.getElementsByTagName("storage").item(0).getTextContent());
long ram = Integer.parseInt(hostElement.getElementsByTagName("ram").item(0).getTextContent());
long bandwidth = SimulationParameters.WAN_BANDWIDTH;
List<Pe> peList = new ArrayList<>();
for (int i = 0; i < numOfCores; i++) {
peList.add(new PeSimple(mips, new PeProvisionerSimple()));
}
ResourceProvisioner ramProvisioner = new ResourceProvisionerSimple();
ResourceProvisioner bwProvisioner = new ResourceProvisionerSimple();
VmScheduler vmScheduler = new VmSchedulerSpaceShared();
Host host = new HostSimple(ram, bandwidth, storage, peList);
host.setRamProvisioner(ramProvisioner).setBwProvisioner(bwProvisioner).setVmScheduler(vmScheduler);
createVms(host, hostElement, bandwidth);
hostList.add(host);
}
return hostList;
}
private void createVms(Host host, Element hostElement, long bandwidth) {
NodeList vmNodeList = hostElement.getElementsByTagName("VM");
for (int k = 0; k < vmNodeList.getLength(); k++) {
Node vmNode = vmNodeList.item(k);
Element vmElement = (Element) vmNode;
long vmNumOfCores = Long.parseLong(vmElement.getElementsByTagName("core").item(0).getTextContent());
double vmMips = Double.parseDouble(vmElement.getElementsByTagName("mips").item(0).getTextContent());
int vmRam = Integer.parseInt(vmElement.getElementsByTagName("ram").item(0).getTextContent());
long vmStorage = Long.parseLong(vmElement.getElementsByTagName("storage").item(0).getTextContent());
long vmBandwidth = bandwidth / vmNodeList.getLength();
CloudletScheduler tasksScheduler= "SPACE_SHARED".equals(SimulationParameters.CPU_ALLOCATION_POLICY) ? new CloudletSchedulerSpaceShared() : new CloudletSchedulerTimeShared();
Vm vm = new VmSimple(vmList.size(), vmMips, vmNumOfCores);
vm.setRam(vmRam).setBw(vmBandwidth).setSize(vmStorage).setCloudletScheduler(tasksScheduler);
vm.setHost(host);
vmList.add(vm);
}
}
public List<DatacenterSimple> getDatacentersList() {
return datacentersList;
}
public List<Vm> getVmList() {
return vmList;
}
}
测试
public class Test {
private static final int CLOUDLETS = 4;
private static final int CLOUDLET_PES = 1;
private static final int CLOUDLET_LENGTH = 10000;
public static void main(String[] args) throws Exception {
new Test();
}
private Test() throws Exception {
CloudSim simulation = new CloudSim();
DatacenterBroker broker0 = new DatacenterBrokerSimple(simulation);
DatacentersManager serversManager = new DatacentersManager(simulation);
serversManager.createDataCenters("mobile/src/main/resources/datacenters.xml");
List<DatacenterSimple> dataCenterList = serversManager.getDatacentersList();
List<Vm> vmList = serversManager.getVmList();
List<Cloudlet> cloudletList = createCloudlets();
broker0.submitVmList(vmList);
broker0.submitCloudletList(cloudletList);
simulation.start();
final List<Cloudlet> finishedCloudlets = broker0.getCloudletFinishedList();
new CloudletsTableBuilder(finishedCloudlets).build();
}
private List<Cloudlet> createCloudlets() {
final List<Cloudlet> list = new ArrayList<>(CLOUDLETS);
final UtilizationModelDynamic utilization = new UtilizationModelDynamic();
final UtilizationModelFull utilizationModelFull = new UtilizationModelFull();
for (int i = 0; i < CLOUDLETS; i++) {
final Cloudlet cloudlet = new CloudletSimple(CLOUDLET_LENGTH, CLOUDLET_PES);
cloudlet.setSizes(1024)
.setUtilizationModelBw(utilization)
.setUtilizationModelRam(utilization)
.setUtilizationModelCpu(utilizationModelFull);
list.add(cloudlet);
}
return list;
}
}
结果
SIMULATION RESULTS
Cloudlet|Status |DC|Host|Host PEs |VM|VM PEs |CloudletLen|CloudletPEs|StartTime|FinishTime|ExecTime
ID| |ID| ID|CPU cores|ID|CPU cores| MI| CPU cores| Seconds| Seconds| Seconds
-----------------------------------------------------------------------------------------------------
2|SUCCESS| 2| 0| 4| 2| 2| 10000| 1| 0| 2| 2
0|SUCCESS| 2| 0| 4| 0| 1| 10000| 1| 0| 10| 10
1|SUCCESS| 2| 0| 4| 1| 1| 10000| 1| 0| 10| 10
3|SUCCESS| 2| 0| 4| 0| 1| 10000| 1| 10| 20| 10
-----------------------------------------------------------------------------------------------------
后记
当不关心虚拟机的调度策略时,可以使用。此外,甚至可以将cloudlet的参数也抽取成配置文件。
|