How to Design and Implement Custom Container Allocation Policies in Cloudsim to Optimize Resource Utilization and Compare Them with Default Policies?
Share
Condition for Design and Implement Custom Container Allocation Policies in Cloudsim
Description: This project implements and evaluates custom container allocation policies within the CloudSim container extension framework. The system features two novel allocation strategies: a threshold-based policy that prevents over-utilization by enforcing CPU and RAM thresholds, and a load-balancing policy that distributes containers evenly across VMs based on current resource utilization. The implementation extends PowerContainerAllocationPolicySimple to incorporate intelligent container placement logic, including resource monitoring, allocation scoring, and constraint enforcement. The framework conducts comparative simulations across multiple policies, measuring key performance metrics including success rates, resource utilization efficiency, execution times, and overall system performance.
/**
* A simple example showing how to create a data center with one host, one VM,
* one container and run one cloudlet on it.
* Modified for Exercise 8: Custom Container-VM Allocation Policy
*/
public class ContainerVmAllocationPolicy { // Renamed class to avoid conflict
/**
* The cloudlet list.
*/
private static List cloudletList;
/**
* The vmlist.
*/
private static List vmList;
/**
* The vmlist.
*/
private static List containerList;
/**
* The hostList.
*/
private static List hostList;
/**
* Custom Container Allocation Policy that ensures VMs have sufficient free resources
*/
public static class CustomContainerAllocationPolicy extends PowerContainerAllocationPolicySimple {
private double cpuThreshold;
private double ramThreshold;
private int allocationAttempts;
private int successfulAllocations;
@Override
public boolean allocateVmForContainer(Container container, ContainerVm vm) {
allocationAttempts++;
// Custom logic: Only allocate if VM has sufficient free resources
double cpuUtilization = vm.getTotalUtilizationOfCpu(CloudSim.clock());
double ramUtilization = (double) vm.getContainerRamProvisioner().getUsedVmRam() / vm.getRam();
// Check if VM has enough CPU and RAM capacity for the container
boolean hasEnoughCpu = (cpuUtilization + (container.getMips() / vm.getMips())) <= cpuThreshold;
boolean hasEnoughRam = vm.getContainerRamProvisioner().isSuitableForContainer(container, container.getRam());
/**
* Alternative Custom Policy: Load Balancing Allocation
*/
public static class LoadBalancingContainerAllocationPolicy extends PowerContainerAllocationPolicySimple {
private int allocationAttempts;
private int successfulAllocations;
@Override
public ContainerVm findVmForContainer(Container container) {
allocationAttempts++;
Log.printLine("LoadBalancing: Finding VM for Container " + container.getId());
/**
* Creates main() to run this example.
*
* @param args the args
*/
public static void main(String[] args) {
Log.printLine("Starting Custom Allocation Policies...");
try {
// Test different allocation policies
testAllocationPolicies();
/**
* Runs a simulation with a specific allocation policy
*/
private static PolicyResult runSimulationWithPolicy(ContainerAllocationPolicy policy, String policyName) {
PolicyResult result = new PolicyResult(policyName);
try {
// Initialize CloudSim
int num_user = 1;
Calendar calendar = Calendar.getInstance();
boolean trace_flag = false;
CloudSim.init(num_user, calendar, trace_flag);
// Use the provided allocation policy
ContainerAllocationPolicy containerAllocationPolicy = policy;
// Define other policies
PowerContainerVmSelectionPolicy vmSelectionPolicy = new PowerContainerVmSelectionPolicyMaximumUsage();
HostSelectionPolicy hostSelectionPolicy = new HostSelectionPolicyFirstFit();
// Create infrastructure
hostList = createHostList(ConstantsExamples.NUMBER_HOSTS);
cloudletList = new ArrayList();
vmList = new ArrayList();
// FIX: Use the correct type and proper casting
PowerContainerVmAllocationPolicyMigrationAbstractHostSelection vmAllocationPolicy =
new PowerContainerVmAllocationPolicyMigrationAbstractHostSelection(
hostList, vmSelectionPolicy, hostSelectionPolicy, overUtilizationThreshold, underUtilizationThreshold);
int overBookingFactor = 80;
ContainerDatacenterBroker broker = createBroker(overBookingFactor);
int brokerId = broker.getId();
} catch (Exception e) {
e.printStackTrace();
Log.printLine("Error in simulation with policy: " + policyName);
} finally {
// Shutdown CloudSim for this run
CloudSim.stopSimulation();
}
return result;
}
/**
* Calculates metrics for policy evaluation
*/
private static void calculatePolicyMetrics(PolicyResult result, List cloudlets, List vms) {
int successfulCloudlets = 0;
double totalExecutionTime = 0;
double totalWaitTime = 0;
for (ContainerCloudlet cloudlet : cloudlets) {
if (cloudlet.getCloudletStatusString().equals("Success")) {
successfulCloudlets++;
totalExecutionTime += cloudlet.getActualCPUTime();
totalWaitTime += cloudlet.getExecStartTime();
}
}
// Calculate VM utilization statistics
double totalCpuUtilization = 0;
double totalRamUtilization = 0;
int utilizedVms = 0;
for (ContainerVm vm : vms) {
double cpuUtil = vm.getTotalUtilizationOfCpu(CloudSim.clock());
double ramUtil = (double) vm.getContainerRamProvisioner().getUsedVmRam() / vm.getRam();
/**
* Data class to store policy results
*/
private static class PolicyResult {
private String policyName;
private int successfulCloudlets;
private int totalCloudlets;
private double avgExecutionTime;
private double avgWaitTime;
private double avgCpuUtilization;
private double avgRamUtilization;
private int utilizedVms;
private long simulationTime;
public PolicyResult(String policyName) {
this.policyName = policyName;
}
// Getters and setters
public String getPolicyName() { return policyName; }
public int getSuccessfulCloudlets() { return successfulCloudlets; }
public void setSuccessfulCloudlets(int successfulCloudlets) { this.successfulCloudlets = successfulCloudlets; }
public int getTotalCloudlets() { return totalCloudlets; }
public void setTotalCloudlets(int totalCloudlets) { this.totalCloudlets = totalCloudlets; }
public double getAvgExecutionTime() { return avgExecutionTime; }
public void setAvgExecutionTime(double avgExecutionTime) { this.avgExecutionTime = avgExecutionTime; }
public double getAvgWaitTime() { return avgWaitTime; }
public void setAvgWaitTime(double avgWaitTime) { this.avgWaitTime = avgWaitTime; }
public double getAvgCpuUtilization() { return avgCpuUtilization; }
public void setAvgCpuUtilization(double avgCpuUtilization) { this.avgCpuUtilization = avgCpuUtilization; }
public double getAvgRamUtilization() { return avgRamUtilization; }
public void setAvgRamUtilization(double avgRamUtilization) { this.avgRamUtilization = avgRamUtilization; }
public int getUtilizedVms() { return utilizedVms; }
public void setUtilizedVms(int utilizedVms) { this.utilizedVms = utilizedVms; }
public long getSimulationTime() { return simulationTime; }
public void setSimulationTime(long simulationTime) { this.simulationTime = simulationTime; }
}
// The following methods remain the same as in the original code
// (createHostList, createVmList, createContainerList, createContainerCloudletList,
// createDatacenter, createBroker, getExperimentName, printCloudletList)
/**
* It creates a specific name for the experiment which is used for creating
* the Log address folder.
*/
private static String getExperimentName(String... args) {
StringBuilder experimentName = new StringBuilder();
for (int i = 0; i < args.length; ++i) {
if (!args[i].isEmpty()) {
if (i != 0) {
experimentName.append("_");
}
experimentName.append(args[i]);
}
}
return experimentName.toString();
}
/**
* Create the Virtual machines and add them to the list
*/
private static ArrayList createVmList(int brokerId, int containerVmsNumber) {
ArrayList containerVms = new ArrayList();
for (int i = 0; i < containerVmsNumber; ++i) {
ArrayList peList = new ArrayList();
int vmType = i / (int) Math.ceil((double) containerVmsNumber / 4.0D);
for (int j = 0; j < ConstantsExamples.VM_PES[vmType]; ++j) {
peList.add(new ContainerPe(j,
new ContainerPeProvisionerSimple((double) ConstantsExamples.VM_MIPS[vmType])));
}
containerVms.add(new PowerContainerVm(IDs.pollId(ContainerVm.class), brokerId,
(double) ConstantsExamples.VM_MIPS[vmType], (float) ConstantsExamples.VM_RAM[vmType],
ConstantsExamples.VM_BW, ConstantsExamples.VM_SIZE, "Xen",
new ContainerSchedulerTimeSharedOverSubscription(peList),
new ContainerRamProvisionerSimple(ConstantsExamples.VM_RAM[vmType]),
new ContainerBwProvisionerSimple(ConstantsExamples.VM_BW),
peList, ConstantsExamples.SCHEDULING_INTERVAL));
}
return containerVms;
}
/**
* Create the host list
*/
public static List createHostList(int hostsNumber) {
ArrayList hostList = new ArrayList();
for (int i = 0; i < hostsNumber; ++i) {
int hostType = i / (int) Math.ceil((double) hostsNumber / 3.0D);
ArrayList peList = new ArrayList();
for (int j = 0; j < ConstantsExamples.HOST_PES[hostType]; ++j) {
peList.add(new ContainerVmPe(j,
new ContainerVmPeProvisionerSimple((double) ConstantsExamples.HOST_MIPS[hostType])));
}
hostList.add(new PowerContainerHostUtilizationHistory(IDs.pollId(ContainerHost.class),
new ContainerVmRamProvisionerSimple(ConstantsExamples.HOST_RAM[hostType]),
new ContainerVmBwProvisionerSimple(1000000L), 1000000L, peList,
new ContainerVmSchedulerTimeSharedOverSubscription(peList),
ConstantsExamples.HOST_POWER[hostType]));
}
return hostList;
}
/**
* Create the data center
*/
public static ContainerDatacenter createDatacenter(String name, Class< extends ContainerDatacenter> datacenterClass,
List hostList,
org.cloudbus.cloudsim.container.resourceAllocators.ContainerVmAllocationPolicy vmAllocationPolicy, // Use fully qualified name
ContainerAllocationPolicy containerAllocationPolicy, String experimentName,
double schedulingInterval, String logAddress, double VMStartupDelay, double ContainerStartupDelay) throws Exception {
String arch = "x86";
String os = "Linux";
String vmm = "Xen";
double time_zone = 10.0D;
double cost = 3.0D;
double costPerMem = 0.05D;
double costPerStorage = 0.001D;
double costPerBw = 0.0D;
/**
* create the containers
*/
public static List createContainerList(int brokerId, int containersNumber) {
ArrayList containers = new ArrayList();
for (int i = 0; i < containersNumber; ++i) {
int containerType = i / (int) Math.ceil((double) containersNumber / 3.0D);
containers.add(new PowerContainer(IDs.pollId(Container.class), brokerId,
(double) ConstantsExamples.CONTAINER_MIPS[containerType],
ConstantsExamples.CONTAINER_PES[containerType],
ConstantsExamples.CONTAINER_RAM[containerType],
ConstantsExamples.CONTAINER_BW, 0L, "Xen",
new ContainerCloudletSchedulerDynamicWorkload(
ConstantsExamples.CONTAINER_MIPS[containerType],
ConstantsExamples.CONTAINER_PES[containerType]),
ConstantsExamples.SCHEDULING_INTERVAL));
}
return containers;
}
/**
* Creating the cloudlet list
*/
public static List createContainerCloudletList(int brokerId, int numberOfCloudlets)
throws FileNotFoundException {
String inputFolderName = "/home/soft13/soft13/Project 2019/Cloudsim-4.0-examples/src/workload/planetlab";
ArrayList cloudletList = new ArrayList();
long fileSize = 300L;
long outputSize = 300L;
UtilizationModelNull utilizationModelNull = new UtilizationModelNull();
java.io.File inputFolder1 = new java.io.File(inputFolderName);
java.io.File[] files1 = inputFolder1.listFiles();
int createdCloudlets = 0;
if (files1 != null) {
for (java.io.File aFiles1 : files1) {
java.io.File inputFolder = new java.io.File(aFiles1.toString());
java.io.File[] files = inputFolder.listFiles();
if (files != null) {
for (int i = 0; i < files.length; ++i) {
if (createdCloudlets < numberOfCloudlets) {
ContainerCloudlet cloudlet = null;
try {
cloudlet = new ContainerCloudlet(IDs.pollId(ContainerCloudlet.class),
ConstantsExamples.CLOUDLET_LENGTH, 1, fileSize, outputSize,
new UtilizationModelPlanetLabInMemoryExtended(files[i].getAbsolutePath(), 300.0D),
utilizationModelNull, utilizationModelNull);
} catch (Exception var13) {
var13.printStackTrace();
System.exit(0);
}
cloudlet.setUserId(brokerId);
cloudletList.add(cloudlet);
createdCloudlets += 1;
} else {
return cloudletList;
}
}
}
}
}
return cloudletList;
}
}