How to Implement a Multi-Datacenter Container Simulation in CloudSim?
Share
Condition for Implement a Multi-Datacenter Container Simulation in CloudSim
Description: The provided code demonstrates a multi-datacenter container simulation using CloudSim. It sets up three datacenters with varying performance characteristics (high, medium, and low), each configured with hosts having different CPU (MIPS), RAM, processing elements (PEs), and bandwidth capacities. The simulation initializes a broker to manage VM and container allocation across these datacenters, ensuring that workloads are efficiently distributed.
Virtual machines (VMs) are created and allocated to the broker, and containers are created on these VMs. Cloudlets representing computational tasks are generated with varying lengths to simulate diverse workloads. Crucially, manual binding ensures that containers are assigned to VMs and cloudlets are assigned to containers.
The simulation uses a PowerContainerVmAllocationPolicyMigrationStaticThreshold for VM allocation with migration policies and monitors resource usage. At the end, the simulation prints detailed results, including workload distribution across datacenters, cloudlet execution status, execution time, and cost analysis, providing insights into performance and resource utilization across multiple datacenters. This setup is particularly useful for evaluating scheduling policies, load balancing, and resource optimization in cloud environments with heterogeneous datacenter configurations.
public static void main(String[] args) {
Log.printLine("Starting Multi-Datacenter Container Simulation...");
try {
// Initialize CloudSim
int numUsers = 1;
Calendar calendar = Calendar.getInstance();
CloudSim.init(numUsers, calendar, false);
// Create first datacenter
List hostList1 = MultiDatacenterHelper.createHostList(4, "DC1");
ContainerVmAllocationPolicy vmAllocationPolicy1 = new PowerContainerVmAllocationPolicyMigrationStaticThreshold(
hostList1, new PowerContainerVmSelectionPolicyMinimumMigrationTime(), 0.8);
ContainerAllocationPolicy containerAllocationPolicy1 = new PowerContainerAllocationPolicySimple();
ContainerDatacenter datacenter1 = MultiDatacenterHelper.createDatacenter(
"Datacenter_1", hostList1, vmAllocationPolicy1, containerAllocationPolicy1);
// Create second datacenter
List hostList2 = MultiDatacenterHelper.createHostList(3, "DC2");
ContainerVmAllocationPolicy vmAllocationPolicy2 = new PowerContainerVmAllocationPolicyMigrationStaticThreshold(
hostList2, new PowerContainerVmSelectionPolicyMinimumMigrationTime(), 0.75);
ContainerAllocationPolicy containerAllocationPolicy2 = new PowerContainerAllocationPolicySimple();
ContainerDatacenter datacenter2 = MultiDatacenterHelper.createDatacenter(
"Datacenter_2", hostList2, vmAllocationPolicy2, containerAllocationPolicy2);
// Create third datacenter (optional)
List hostList3 = MultiDatacenterHelper.createHostList(2, "DC3");
ContainerVmAllocationPolicy vmAllocationPolicy3 = new PowerContainerVmAllocationPolicyMigrationStaticThreshold(
hostList3, new PowerContainerVmSelectionPolicyMinimumMigrationTime(), 0.85);
ContainerAllocationPolicy containerAllocationPolicy3 = new PowerContainerAllocationPolicySimple();
ContainerDatacenter datacenter3 = MultiDatacenterHelper.createDatacenter(
"Datacenter_3", hostList3, vmAllocationPolicy3, containerAllocationPolicy3);
// Create broker with inter-datacenter load balancing
ContainerDatacenterBroker broker = new ContainerDatacenterBroker("MultiDC_Broker", 80);
// Create VMs, Containers and Cloudlets
List vmList = MultiDatacenterHelper.createVmList(broker.getId(), 12);
List containerList = MultiDatacenterHelper.createContainerList(broker.getId(), 24);
List cloudletList = MultiDatacenterHelper.createCloudletList(broker.getId(), 24);
// Submit to broker - workload will be distributed across datacenters
// Submit to broker - workload will be distributed across datacenters
broker.submitVmList(vmList);
broker.submitContainerList(containerList);
broker.submitCloudletList(cloudletList);
// Manually bind Containers to VMs (important!)
for (int i = 0; i < containerList.size(); i++) {
broker.bindCloudletToContainer(containerList.get(i).getId(), vmList.get(i % vmList.size()).getId());
}
// Manually bind Cloudlets to Containers
for (int i = 0; i < cloudletList.size(); i++) {
broker.bindCloudletToContainer(cloudletList.get(i).getContainerId(), containerList.get(i % containerList.size()).getId());
}
// Increase runtime to ensure full execution
CloudSim.terminateSimulation(100000.0);
// Start Simulation
CloudSim.startSimulation();
// Get results
List newList = broker.getCloudletReceivedList();
CloudSim.stopSimulation();
// Print results with datacenter information
MultiDatacenterHelper.printMultiDCResults(newList,
Arrays.asList(datacenter1, datacenter2, datacenter3));
// Different configurations for different datacenters
private static final Map DC_CONFIGS = new HashMap<>();
static {
// High-performance datacenter
DC_CONFIGS.put("DC1", new DCConfig(
new int[]{3000, 4000, 5000}, // MIPS
new int[]{16384, 32768, 65536}, // RAM (MB)
new int[]{8, 12, 16}, // PEs
new int[]{20000, 25000, 30000} // BW
));
// Medium-performance datacenter
DC_CONFIGS.put("DC2", new DCConfig(
new int[]{2000, 3000, 4000},
new int[]{8192, 16384, 32768},
new int[]{4, 8, 12},
new int[]{15000, 20000, 25000}
));
// Low-performance datacenter
DC_CONFIGS.put("DC3", new DCConfig(
new int[]{1000, 2000, 3000},
new int[]{4096, 8192, 16384},
new int[]{2, 4, 8},
new int[]{10000, 15000, 20000}
));
}
// VM specifications
private static final int[] VM_MIPS = {1000, 2000, 3000};
private static final int[] VM_RAM = {1024, 2048, 4096};
private static final int[] VM_PES = {1, 2, 4};
private static final int VM_BW = 2000;
private static final int VM_SIZE = 10000;
// Container specifications
private static final int[] CONTAINER_MIPS = {500, 750, 1000};
private static final int[] CONTAINER_RAM = {256, 512, 1024};
private static final int[] CONTAINER_PES = {1, 1, 2};
private static final int CONTAINER_BW = 1000;
// Cloudlet specifications
private static final int CLOUDLET_LENGTH = 15000;
private static final int CLOUDLET_PES = 1;
private static final int CLOUDLET_FILE_SIZE = 500;
private static final int CLOUDLET_OUTPUT_SIZE = 500;
public static List createHostList(int numberOfHosts, String dcType) {
List hostList = new ArrayList<>();
DCConfig config = DC_CONFIGS.getOrDefault(dcType, DC_CONFIGS.get("DC1"));
for (int i = 0; i < numberOfHosts; i++) {
int hostType = i % config.mips.length;
List peList = new ArrayList<>();
for (int j = 0; j < config.pes[hostType]; j++) {
peList.add(new ContainerVmPe(j,
new ContainerVmPeProvisionerSimple(config.mips[hostType])));
}
ContainerHost host = new PowerContainerHostUtilizationHistory(
IDs.pollId(ContainerHost.class),
new ContainerVmRamProvisionerSimple(config.ram[hostType]),
new ContainerVmBwProvisionerSimple(config.bw[hostType]),
2000000, // storage
peList,
new ContainerVmSchedulerTimeSharedOverSubscription(peList),
new PowerModelLinear(config.mips[hostType], 350) // power capacity
);
public static List createVmList(int brokerId, int numberOfVms) {
List vmList = new ArrayList<>();
for (int i = 0; i < numberOfVms; i++) {
int vmType = i % VM_MIPS.length;
List peList = new ArrayList<>();
for (int j = 0; j < VM_PES[vmType]; j++) {
peList.add(new ContainerPe(j,
new ContainerPeProvisionerSimple(VM_MIPS[vmType])));
}
ContainerVm vm = new PowerContainerVm(
IDs.pollId(ContainerVm.class),
brokerId,
VM_MIPS[vmType],
VM_RAM[vmType],
VM_BW,
VM_SIZE,
"Xen",
new ContainerSchedulerTimeSharedOverSubscription(peList),
new ContainerRamProvisionerSimple(VM_RAM[vmType]),
new ContainerBwProvisionerSimple(VM_BW),
peList,
300 // scheduling interval
);
public static List createCloudletList(int brokerId, int numberOfCloudlets) {
List cloudletList = new ArrayList<>();
// Create cloudlets with different utilization patterns
Random rand = new Random();
for (int i = 0; i < numberOfCloudlets; i++) {
// Vary cloudlet length for workload diversity
int cloudletLength = CLOUDLET_LENGTH + rand.nextInt(5000) - 2500;
ContainerCloudlet cloudlet = new ContainerCloudlet(
IDs.pollId(ContainerCloudlet.class),
cloudletLength,
CLOUDLET_PES,
CLOUDLET_FILE_SIZE,
CLOUDLET_OUTPUT_SIZE,
new UtilizationModelFull(),
new UtilizationModelFull(),
new UtilizationModelFull()
);
private static double getTimeZoneForDC(String dcName) {
switch (dcName) {
case "Datacenter_1": return 10.0; // Australia
case "Datacenter_2": return -5.0; // US East
case "Datacenter_3": return 1.0; // Europe
default: return 0.0;
}
}
private static double getCostForDC(String dcName) {
switch (dcName) {
case "Datacenter_1": return 4.0; // Premium
case "Datacenter_2": return 2.5; // Standard
case "Datacenter_3": return 1.5; // Budget
default: return 3.0;
}
}
public static void printMultiDCResults(List cloudletList,
List datacenters) {
String indent = " ";
DecimalFormat dft = new DecimalFormat("###.##");
// Group cloudlets by datacenter
Map> cloudletsByDC = cloudletList.stream()
.collect(Collectors.groupingBy(ContainerCloudlet::getResourceId));
// Print distribution across datacenters
Log.printLine("\nWORKLOAD DISTRIBUTION:");
for (ContainerDatacenter dc : datacenters) {
int dcId = dc.getId();
List dcCloudlets = cloudletsByDC.getOrDefault(dcId, new ArrayList<>());
long successful = dcCloudlets.stream()
.filter(c -> c.getCloudletStatus() == Cloudlet.SUCCESS)
.count();