利用CloudSim进行云计算实验的实践指南
1. 云计算与CloudSim简介
云计算近年来发展迅猛,因其具备安全性高和可扩展性强等特点,能够通过互联网动态交付IT资源。CloudSim是一款可用于实现和测试云场景的模拟器,接下来将详细介绍其架构、安装步骤以及不同的使用示例。
2. CloudSim架构
CloudSim采用多层编程结构,其初始版本使用SimJava作为离散事件模拟设计,支持事件处理、组件通信和模拟时钟管理等核心功能。离散事件模拟(DES)将系统活动建模为一系列离散的时间事件,每个事件在特定时刻发生并导致系统状态改变,在连续事件之间系统状态保持不变,模拟时间可直接跳转到下一个事件的时间。当前版本中,SimJava层已被移除,以支持更高级的操作。
CloudSim模拟层为虚拟化的基于云的服务器数据中心环境提供建模和模拟支持,包括VM、内存、存储和数据传输的专用管理接口,负责处理主机分配给VM以及管理应用执行状态等关键问题。
数据中心管理多个主机元素,主机根据VM分配策略映射到至少一个VM,该策略由云服务提供商定义,涵盖VM生命周期的任务控制安排,如主机分配、VM创建、故障处理和迁移等。在云计算中,一个VM实例可以提供至少一个应用服务,即应用供应。
在CloudSim中,实体是组件的实例,组件可以是类或类集,代表一个CloudSim模型(如数据中心、主机等)。数据中心管理多个主机,主机在VM生命周期内进行管理。主机代表云中的物理计算服务器,具有预配置的处理能力(以每秒百万条指令 - MIPS表示)、内存、存储和处理核心分配策略,支持单核心和多核心节点的建模和模拟。每个主机组件根据主机分配策略将处理核心分配给VM,该策略考虑CPU核心数量、CPU份额和内存等硬件特性。CloudSim支持多种模拟场景,如将特定CPU核心分配给特定VM(空间共享策略)、动态分配核心容量(时间共享策略)或按需分配核心。
CloudSim可在任何集成开发环境(IDE)中运行,以下是在Eclipse IDE中安装CloudSim的步骤:
1. 打开Eclipse,点击“java project”。
2. 输入项目名称。
3. 自动创建项目路径。
4. 选择JRE环境。
5. 输入项目名称,选择运行时环境,然后点击“Finish”。
6. 进入提取Cloudsim工具的目录。
7. 选择Cloudsim,点击“Finish”。
8. 访问链接http://commons.apache.org/proper/commonsmath/download math.cgi 。
9. 下载名为“commons - math3 - 3.4.1 - bin.zip”的文件并解压,获取数学函数所需的jar文件。
10. 在Eclipse工具的项目栏左侧,右键点击“jar”,选择“import”,导入数学计算所需的jar文件。
11. 进入下载并解压文件的文件夹,选择“Import only jar”。
12. 最终,CloudSim成功安装到Eclipse环境中。
mermaid图展示CloudSim架构:
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(User Code):::process --> B(Scheduling specification):::process
A --> C(Simulation policy):::process
B --> D(User or Data center broker):::process
C --> D
D --> E(Cloud scenario):::process
E --> F(User requirements):::process
F --> G(Application configuration):::process
G --> H(User Interface Structures):::process
H --> I(VM services):::process
H --> J(Cloud services):::process
H --> K(Cloud resources):::process
H --> L(Network):::process
I --> M(Cloudlet):::process
I --> N(VM):::process
M --> O(Cloudlet execution):::process
N --> P(VM management):::process
N --> Q(VM provisioning):::process
P --> R(CPU allocation):::process
P --> S(Memory):::process
P --> T(Storage allocation):::process
P --> U(Bandwidth allocation):::process
O --> V(Event handling):::process
V --> W(Sensor):::process
V --> X(Cloud coordinator):::process
V --> Y(Data center):::process
V --> Z(Network topology):::process
Z --> AA(Message delay calculation):::process
AA --> AB(allocation):::process
V --> AC(Cloud Core Simulation Engine):::process
3. CloudSim示例
3.1 CloudSim示例1:创建一个带有一个主机的数据中心并运行一个Cloudlet
算法步骤如下:
1. 初始化CloudSim包,此步骤应在创建任何实体之前进行。
2. 创建数据中心。
3. 创建代理。
4. 创建一个VM。
5. 将VM添加到vmList。
6. 向代理提交VM列表。
7. 创建一个具有指定属性(id、长度、文件大小等)的Cloudlet。
8. 将Cloudlet添加到列表。
9. 向代理提交Cloudlet列表。
10. 启动模拟。
11. 模拟结束后打印结果。
12. 打印Cloudlet对象信息。
源代码如下:
public class CloudSimExample1
{
private static List<Cloudlet> CloudletList;
private static List< Vm > vmlist;
public static void main(String[] args)
{
try {
int num_user = 1;
Calendar calendar = Calendar.getInstance();
boolean trace_flag = false;
CloudSim.init(num_user, calendar, trace_flag);
Datacenter datacenter0 = createDatacenter("Datacenter 0");
DatacenterBroker broker = createBroker();
int brokerId = broker.getId();
vmlist = new ArrayList< Vm >();
int vmid = 0;
int mips = 1000;
long size = 10000;
int ram = 512;
long bw = 1000;
int pesNumber = 1;
String vmm = "Xen";
Vm vm = new Vm(vmid, brokerId, mips, pesNumber, ram, bw, size, vmm,
new CloudletSchedulerTimeShared());
vmlist.add(vm);
broker.submitVmList(vmlist);
CloudletList = new ArrayList< Cloudlet >();
int id = 0;
length = 400000;
fileSize = 300;
outputSize = 300;
utilizationModel = new UtilizationModelFull();
Cloudlet Cloudlet = new Cloudlet(id, length, pesNumber, fileSize,outputSize,
utilizationModel, utilizationModel,utilizationModel);
Cloudlet.setUserId(brokerId);
Cloudlet.setVmId(vmid);
CloudletList.add(Cloudlet);
broker.submitCloudletList(CloudletList);
CloudSim.startSimulation();
CloudSim.stopSimulation();
List< Cloudlet > newList = broker.getCloudletReceivedList();
printCloudletList(newList);
Log.printLine("CloudSimExample1 finished!");
}
catch (Exception e)
{
e.printStackTrace();
Log.printLine("Unwanted errors happen");
}
}
private static Datacenter createDatacenter(String name) {
List< Host > hostList = new ArrayList< Host >();
List< Pe > peList = new ArrayList< Pe >();
int mips = 1000;
peList.add(new Pe(0, new PeProvisionerSimple(mips)));
int hostId = 0;
int ram = 2048;
long storage = 1000000;
int bw = 10000;
hostList.add(new Host(hostId,new RamProvisionerSimple(ram),new BwProvisionerSimple(bw),storage,peList,new VmSchedulerTimeShared(peList)));
String arch = "x86";
String os = "Linux";
String vmm = "Xen";
double time_zone = 10.0;
double cost = 3.0;
double costPerMem = 0.05;
double costPerStorage = 0.001;
double costPerBw = 0.0;
LinkedList< Storage > storageList = new LinkedList< Storage >();
DatacenterCharacteristics characteristics = new DatacenterCharacteristics(arch, os, vmm, hostList, time_zone, cost, costPerMem,
costPerStorage, costPerBw);
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;
Log.printLine("========== OUTPUT ==========");
Log.printLine("Cloudlet ID" + "STATUS" + "Data center ID" + "VM ID"
+ "Time" + "Start Time" + "Finish Time");
for (int i = 0; i < size; i++)
{
Cloudlet = list.get(i);
Log.print(Cloudlet.getCloudletId());
if (Cloudlet.getCloudletStatus() == Cloudlet.SUCCESS)
{
Log.print("SUCCESS");
Log.printLine(Cloudlet.getResourceId() + Cloudlet.getVmId() + Cloudlet.getActualCPUTime()) + Cloudlet.getExecStartTime())
+ Cloudlet.getFinishTime());
}
}
}
}
输出结果如下表所示:
| Cloudlet ID | STATUS | Data Center ID | VM ID | Time (ms) | Start Time | Finish Time |
| — | — | — | — | — | — | — |
| 0 | success | 2 | 0 | 400 | 0.1 | 400.1 |
3.2 CloudSim示例2:创建两个各带一个主机和网络拓扑的数据中心并运行两个Cloudlet
算法步骤如下:
1. 初始化CloudSim包。
2. 初始化CloudSim库。
3. 创建数据中心。
4. 创建代理。
5. 创建两个VM。
6. 将VM添加到vmList。
7. 向代理提交VM列表。
8. 创建两个Cloudlet。
9. 将Cloudlet添加到列表。
10. 向代理提交Cloudlet列表。
11. 将Cloudlet绑定到VM。
12. 启动模拟。
13. 模拟结束后打印结果。
14. 创建主机并添加到列表。
15. 创建数据中心特性对象。
16. 创建PowerDatacenter对象。
17. 打印Cloudlet对象信息。
源代码如下:
public class CloudSimExample2
{
private static List< Cloudlet > CloudletList;
private static List< Vm > vmlist;
public static void main(String[] args)
{
try
{
int num_user = 1;
Calendar calendar = Calendar.getInstance();
boolean trace_flag = false;
CloudSim.init(num_user, calendar, trace_flag);
Datacenter datacenter0 = createDatacenter("Datacenter 0");
DatacenterBroker broker = createBroker();
int brokerId = broker.getId();
vmlist = new ArrayList< Vm >();
int vmid = 0;
int mips = 250;
long size = 10000;
int ram = 512;
long bw = 1000;
int pesNumber = 1;
String vmm = "Xen";
Vm vm1 = new Vm(vmid, brokerId, mips, pesNumber, ram, bw, size, vmm,
new CloudletSchedulerTimeShared());
vmid++;
Vm vm2 = new Vm(vmid, brokerId, mips, pesNumber, ram, bw, size, vmm,
new CloudletSchedulerTimeShared());
vmlist.add(vm1);
vmlist.add(vm2);
broker.submitVmList(vmlist);
CloudletList = new ArrayList< Cloudlet >();
int id = 0;
pesNumber = 1;
long length = 250000;
long fileSize = 300;
long outputSize = 300;
UtilizationModel utilizationModel = new UtilizationModelFull();
Cloudlet Cloudlet1 = new Cloudlet(id, length, pesNumber, fileSize, outputSize, utilizationModel, utilizationModel, utilizationModel);
Cloudlet1.setUserId(brokerId);
id++;
Cloudlet Cloudlet2 = new Cloudlet(id, length, pesNumber, fileSize, outputSize, utilizationModel, utilizationModel, utilizationModel);
Cloudlet2.setUserId(brokerId);
CloudletList.add(Cloudlet1);
CloudletList.add(Cloudlet2);
broker.submitCloudletList(CloudletList);
broker.bindCloudletToVm(Cloudlet1.getCloudletId(), vm1.getId());
broker.bindCloudletToVm(Cloudlet2.getCloudletId(), vm2.getId());
CloudSim.startSimulation();
List< Cloudlet > newList = broker.getCloudletReceivedList();
CloudSim.stopSimulation();
printCloudletList(newList);
Log.printLine("CloudSimExample2 finished!");
}
catch (Exception e)
{
e.printStackTrace();
Log.printLine("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 >();
int mips = 1000;
peList.add(new Pe(0, new PeProvisionerSimple(mips)));
int hostId = 0;
int ram = 2048;
long storage = 1000000;
int bw = 10000;
hostList.add(new Host(hostId, new RamProvisionerSimple(ram), new BwProvisionerSimple(bw), storage, peList, new VmSchedulerTimeShared(peList)));
String arch = "x86";
String os = "Linux";
String vmm = "Xen";
double time_zone = 10.0;
double cost = 3.0;
double costPerMem = 0.05;
double costPerStorage = 0.001;
double costPerBw = 0.0;
LinkedList< Storage > storageList = new LinkedList< Storage >();
DatacenterCharacteristics characteristics = new DatacenterCharacteristics(arch, os, vmm, hostList, time_zone, cost, costPerMem, costPerStorage, costPerBw);
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;
Log.printLine("========== OUTPUT ==========");
Log.printLine("Cloudlet ID" + "STATUS" + "Data center ID" + "VM ID"
+ "Time" + "Start Time" + "Finish Time");
for (int i = 0; i < size; i++)
{
Cloudlet = list.get(i);
Log.print(Cloudlet.getCloudletId());
if (Cloudlet.getCloudletStatus() == Cloudlet.SUCCESS)
{
Log.print("SUCCESS");
Log.printLine(Cloudlet.getResourceId() + Cloudlet.getVmId() + (Cloudlet.getActualCPUTime()) +
Cloudlet.getExecStartTime()) + (Cloudlet.getFinishTime());
}
}
}
}
输出结果如下表所示:
| Cloudlet ID | STATUS | Data Center ID | VM ID | Time | Start Time | Finish Time |
| — | — | — | — | — | — | — |
| 0 | success | 2 | 0 | 1000 | 0.1 | 1000.1 |
| 1 | success | 2 | 0 | 1000 | 0.1 | 1000.1 |
3.3 CloudSim示例3:创建两个各带一个主机的数据中心并运行两个用户的Cloudlet,同时考虑网络拓扑
算法步骤如下:
1. 初始化CloudSim包,此步骤需在创建任何实体之前完成。
2. 创建数据中心,数据中心是CloudSim中的资源提供者,至少需要一个数据中心才能运行模拟。
3. 创建代理。
4. 创建一个虚拟机。
5. 再创建一个虚拟机,且第二个虚拟机的优先级是第一个的两倍,将获得两倍的CPU时间。
6. 将虚拟机添加到虚拟机列表。
7. 向代理提交虚拟机列表。
8. 创建两个Cloudlet。
9. 向代理提交Cloudlet列表。
10. 将Cloudlet绑定到虚拟机,这样代理只会将绑定的Cloudlet提交到特定的虚拟机。
11. 启动模拟。
12. 模拟结束后打印结果。
13. 创建PowerDatacenter。
14. 创建处理单元(PE)并添加到列表。
15. 创建主机并添加到机器列表。
16. 创建数据中心特性对象,存储数据中心的架构、操作系统、机器列表、分配策略、时区和价格等属性。
17. 最后创建PowerDatacenter对象。
源代码如下:
public class CloudSimExample3
{
private static List< Cloudlet > CloudletList;
private static List< Vm > vmlist;
public static void main(String[] args)
{
Log.printLine("Starting CloudSimExample3...");
try
{
int num_user = 1;
Calendar calendar = Calendar.getInstance();
boolean trace_flag = false;
CloudSim.init(num_user, calendar, trace_flag);
Datacenter datacenter0 = createDatacenter("Datacenter 0");
DatacenterBroker broker = createBroker();
int brokerId = broker.getId();
vmlist = new ArrayList< Vm >();
int vmid = 0;
int mips = 250;
long size = 10000;
int ram = 2048;
long bw = 1000;
int pesNumber = 1;
String vmm = "Xen";
Vm vm1 = new Vm(vmid, brokerId, mips, pesNumber, ram, bw, size, vmm,
new CloudletSchedulerTimeShared());
vmid++;
Vm vm2 = new Vm(vmid, brokerId, mips * 2, pesNumber, ram, bw, size,
vmm, new CloudletSchedulerTimeShared());
vmlist.add(vm1);
vmlist.add(vm2);
broker.submitVmList(vmlist);
CloudletList = new ArrayList< Cloudlet >();
int id = 0;
long length = 40000;
long fileSize = 300;
long outputSize = 300;
UtilizationModel utilizationModel = new UtilizationModelFull();
Cloudlet Cloudlet1 = new Cloudlet(id, length, pesNumber, fileSize, outputSize, utilizationModel, utilizationModel, utilizationModel);
Cloudlet1.setUserId(brokerId);
id++;
Cloudlet Cloudlet2 = new Cloudlet(id, length, pesNumber, fileSize, outputSize, utilizationModel, utilizationModel, utilizationModel);
Cloudlet2.setUserId(brokerId);
CloudletList.add(Cloudlet1);
CloudletList.add(Cloudlet2);
broker.submitCloudletList(CloudletList);
broker.bindCloudletToVm(Cloudlet1.getCloudletId(),vm1.getId());
broker.bindCloudletToVm(Cloudlet2.getCloudletId(),vm2.getId());
CloudSim.startSimulation();
List< Cloudlet > newList = broker.getCloudletReceivedList();
CloudSim.stopSimulation();
printCloudletList(newList);
Log.printLine("CloudSimExample3 finished!");
}
catch (Exception e)
{
e.printStackTrace();
Log.printLine("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 >();
int mips = 1000;
peList.add(new Pe(0, new PeProvisionerSimple(mips)));
int hostId = 0;
int ram = 2048;
long storage = 1000000;
int bw = 10000;
hostList.add(new Host(hostId, new RamProvisionerSimple(ram), new BwProvisionerSimple(bw), storage, peList, new VmSchedulerTimeShared(peList)));
List< Pe > peList2 = new ArrayList< Pe >();
peList2.add(new Pe(0, new PeProvisionerSimple(mips)));
hostId++;
hostList.add(new Host(hostId, new RamProvisionerSimple(ram), new BwProvisionerSimple(bw), storage, peList2, new VmSchedulerTimeShared(peList2)));
String arch = "x86";
String os = "Linux";
String vmm = "Xen";
double time_zone = 10.0;
double cost = 3.0;
double costPerMem = 0.05;
double costPerStorage = 0.001;
double costPerBw = 0.0;
LinkedList< Storage > storageList = new LinkedList< Storage >();
DatacenterCharacteristics characteristics = new DatacenterCharacteristics(arch, os, vmm, hostList, time_zone, cost, costPerMem, costPerStorage, costPerBw);
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;
Log.printLine("========== OUTPUT ==========");
Log.printLine("Cloudlet ID" + "STATUS" + "Data center ID" + "VM ID"
+ "Time" + "Start Time" + "Finish Time");
for (int i = 0; i < size; i++)
{
Cloudlet = list.get(i);
Log.print(Cloudlet.getCloudletId());
if (Cloudlet.getCloudletStatus() == Cloudlet.SUCCESS)
{
Log.print("SUCCESS");
Log.printLine(Cloudlet.getResourceId() + Cloudlet.getVmId() + Cloudlet.getActualCPUTime() +
Cloudlet.getExecStartTime() + Cloudlet.getFinishTime());
}
}
}
}
输出结果如下表所示:
| Cloudlet ID | STATUS | Data Center ID | VM ID | Time | Start Time | Finish Time |
| — | — | — | — | — | — | — |
| 待补充 | 待补充 | 待补充 | 待补充 | 待补充 | 待补充 | 待补充 |
4. 总结
CloudSim是一款功能强大的云计算模拟器,它提供了一个灵活的平台,可用于模拟各种云环境和场景。通过上述介绍,我们了解了CloudSim的架构,包括其多层结构和各层的功能,以及如何在Eclipse IDE中进行安装。同时,通过三个不同的示例,展示了如何使用CloudSim创建数据中心、虚拟机和Cloudlet,并运行模拟以观察不同配置下的运行结果。
这些示例涵盖了从简单的单主机单Cloudlet场景到复杂的多数据中心、多用户和多虚拟机的场景,为我们深入理解云计算环境中的资源分配、任务调度和性能评估提供了实践基础。无论是研究人员进行学术研究,还是开发人员进行云应用的测试和优化,CloudSim都能提供有价值的帮助。
在实际应用中,我们可以根据具体需求对示例代码进行修改和扩展,以模拟更复杂的云场景,例如考虑不同的资源分配策略、网络拓扑结构和用户需求等。同时,还可以结合其他工具和技术,进一步提升模拟的准确性和实用性。
mermaid图展示CloudSim使用流程:
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(初始化CloudSim包):::process --> B(创建数据中心):::process
B --> C(创建代理):::process
C --> D(创建虚拟机):::process
D --> E(添加虚拟机到列表):::process
E --> F(提交虚拟机列表到代理):::process
F --> G(创建Cloudlet):::process
G --> H(添加Cloudlet到列表):::process
H --> I(提交Cloudlet列表到代理):::process
I --> J(绑定Cloudlet到虚拟机):::process
J --> K(启动模拟):::process
K --> L(停止模拟):::process
L --> M(打印结果):::process
通过掌握CloudSim的使用,我们能够更好地探索云计算的潜力,优化云资源的利用,为构建高效、可靠的云服务提供支持。希望本文的内容能为读者在云计算领域的学习和实践提供有益的参考。
超级会员免费看
9629

被折叠的 条评论
为什么被折叠?



