How to Cloudlet Migrate from One Container to Another in Containercloudsim?
Share
Condition for Cloudlet Migrate from One Container to Another in Containercloudsim
Description: In ContainerCloudSim, cloudlet migration from one container to another involves transferring the execution of a cloudlet (computational task) from its current container to a different container while preserving its state and progress. This process is essential for dynamic resource management, load balancing, fault tolerance, and energy efficiency in cloud data centers. The migration mechanism operates through a coordinated sequence of steps: first, the system identifies the need for migration based on factors like container overload, resource optimization requirements, or host maintenance needs. The cloudlet's current execution state, including completed instructions, memory content, and processing context, is captured and serialized.
The target container is selected based on resource availability, proximity, and performance criteria. During the actual migration, the cloudlet is temporarily paused in the source container, its state is transferred to the destination container, and execution resumes seamlessly with minimal disruption. The ContainerDatacenterBroker manages this process by tracking cloudlet-container mappings and updating scheduling parameters. This migration capability enables dynamic workload redistribution, improves resource utilization, maintains quality of service during container failures, and allows for live maintenance operations without service interruption, making the cloud infrastructure more adaptive and resilient to changing workload patterns and system conditions.
Sample Code
1. SourceCode1:
package ContainerMigration;
import org.cloudbus.cloudsim.Log;
import org.cloudbus.cloudsim.Storage;
import org.cloudbus.cloudsim.UtilizationModelNull;
import org.cloudbus.cloudsim.container.containerProvisioners.ContainerBwProvisionerSimple;
import org.cloudbus.cloudsim.container.containerProvisioners.ContainerPe;
import org.cloudbus.cloudsim.container.containerProvisioners.ContainerRamProvisionerSimple;
import org.cloudbus.cloudsim.container.containerProvisioners.ContainerPeProvisionerSimple;
import org.cloudbus.cloudsim.container.containerVmProvisioners.ContainerVmBwProvisionerSimple;
import org.cloudbus.cloudsim.container.containerVmProvisioners.ContainerVmPe;
import org.cloudbus.cloudsim.container.containerVmProvisioners.ContainerVmPeProvisionerSimple;
import org.cloudbus.cloudsim.container.containerVmProvisioners.ContainerVmRamProvisionerSimple;
import org.cloudbus.cloudsim.container.core.*;
import org.cloudbus.cloudsim.container.hostSelectionPolicies.HostSelectionPolicy;
import org.cloudbus.cloudsim.container.hostSelectionPolicies.HostSelectionPolicyFirstFit;
import org.cloudbus.cloudsim.container.resourceAllocatorMigrationEnabled .PowerContainerVmAllocationPolicyMigrationAbstractHostSelection;
import org.cloudbus.cloudsim.container.resourceAllocators.ContainerAllocationPolicy;
import org.cloudbus.cloudsim.container.resourceAllocators.ContainerVmAllocationPolicy;
import org.cloudbus.cloudsim.container.resourceAllocators.PowerContainerAllocationPolicySimple;
import org.cloudbus.cloudsim.container.schedulers.ContainerCloudletSchedulerDynamicWorkload;
import org.cloudbus.cloudsim.container.schedulers.ContainerSchedulerTimeSharedOverSubscription;
import org.cloudbus.cloudsim.container.schedulers.ContainerVmSchedulerTimeSharedOverSubscription;
import org.cloudbus.cloudsim.container.utils.IDs;
import org.cloudbus.cloudsim.container.vmSelectionPolicies.PowerContainerVmSelectionPolicy;
import org.cloudbus.cloudsim.container.vmSelectionPolicies .PowerContainerVmSelectionPolicyMaximumUsage;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.container.core.PowerContainer;
import java.io.FileNotFoundException;
import java.text.DecimalFormat;
import java.util.*;
import org.cloudbus.cloudsim.examples.container.ConstantsExamples;
import org.cloudbus.cloudsim.examples.container.UtilizationModelPlanetLabInMemoryExtended;
/**
* Enhanced ContainerCloudSim with Cloudlet Migration Capabilities
*/
public class ContainerMigration {
private static List cloudletList;
private static List vmList;
private static List containerList;
private static List hostList;
private static EnhancedContainerDatacenterBroker broker;
private final List submittedContainers = new ArrayList<>();
public static void main(String[] args) {
Log.printLine("🚀 Starting Enhanced ContainerCloudSim with Migration Capabilities...");
try {
int num_user = 1;
Calendar calendar = Calendar.getInstance();
boolean trace_flag = false;
CloudSim.init(num_user, calendar, trace_flag);
ContainerAllocationPolicy containerAllocationPolicy = new PowerContainerAllocationPolicySimple();
PowerContainerVmSelectionPolicy vmSelectionPolicy = new PowerContainerVmSelectionPolicyMaximumUsage();
HostSelectionPolicy hostSelectionPolicy = new HostSelectionPolicyFirstFit();
double overUtilizationThreshold = 0.80;
double underUtilizationThreshold = 0.70;
hostList = new ArrayList();
hostList = createHostList(ConstantsExamples.NUMBER_HOSTS);
cloudletList = new ArrayList();
vmList = new ArrayList();
ContainerVmAllocationPolicy vmAllocationPolicy = new PowerContainerVmAllocationPolicyMigrationAbstractHostSelection(
hostList, vmSelectionPolicy, hostSelectionPolicy, overUtilizationThreshold, underUtilizationThreshold);
int overBookingFactor = 80;
broker = createEnhancedBroker(overBookingFactor);
int brokerId = broker.getId();
cloudletList = createContainerCloudletList(brokerId, ConstantsExamples.NUMBER_CLOUDLETS);
containerList = createContainerList(brokerId, ConstantsExamples.NUMBER_CLOUDLETS);
vmList = createVmList(brokerId, ConstantsExamples.NUMBER_VMS);
String logAddress = "~/Results";
@SuppressWarnings("unused")
PowerContainerDatacenter datacenter = (PowerContainerDatacenter) createDatacenter("datacenter",
PowerContainerDatacenterCM.class, hostList, vmAllocationPolicy, containerAllocationPolicy,
getExperimentName("ContainerCloudSim-Migration", String.valueOf(overBookingFactor)),
ConstantsExamples.SCHEDULING_INTERVAL, logAddress,
ConstantsExamples.VM_STARTTUP_DELAY, ConstantsExamples.CONTAINER_STARTTUP_DELAY);
broker.submitCloudletList(cloudletList.subList(0, containerList.size()));
broker.submitContainerList(containerList);
broker.submitVmList(vmList);
// Schedule cloudlet migrations
scheduleCloudletMigrations();
CloudSim.terminateSimulation(86400.00);
CloudSim.startSimulation();
CloudSim.stopSimulation();
List newList = broker.getCloudletReceivedList();
printCloudletList(newList);
Log.printLine(" ContainerCloudSim with Migration finished successfully!");
} catch (Exception e) {
e.printStackTrace();
Log.printLine(" Unwanted errors occurred");
}
}
/**
* Schedule cloudlet migrations for demonstration
*/
private static void scheduleCloudletMigrations() {
Log.printLine("\n SCHEDULING CLOUDLET MIGRATIONS:");
if (cloudletList.size() >= 3 && containerList.size() >= 3) {
// Migration 1: Cloudlet 0 from Container 0 to Container 1 at time 500
broker.migrateCloudlet(cloudletList.get(0).getCloudletId(),
containerList.get(0).getId(),
containerList.get(1).getId(), 500.0);
// Migration 2: Cloudlet 1 from Container 1 to Container 2 at time 1000
broker.migrateCloudlet(cloudletList.get(1).getCloudletId(),
containerList.get(1).getId(),
containerList.get(2).getId(), 1000.0);
// Migration 3: Cloudlet 2 from Container 2 to Container 0 at time 1500
broker.migrateCloudlet(cloudletList.get(2).getCloudletId(),
containerList.get(2).getId(),
containerList.get(0).getId(), 1500.0);
} else {
Log.printLine(" Not enough cloudlets/containers for migration demonstration");
}
// Print initial status
printCloudletStatus("Initial Status");
}
/**
* Print current cloudlet status
*/
private static void printCloudletStatus(String phase) {
Log.printLine("\n CLOUDLET STATUS - " + phase + " (Time: " + String.format("%.2f", CloudSim.clock()) + ")");
Log.printLine("Cloudlet ID | Container ID | Status | Start Time | Finish Time");
Log.printLine("------------|-------------|------------|------------|------------");
DecimalFormat dft = new DecimalFormat("###.##");
for (ContainerCloudlet cloudlet : cloudletList) {
String status = getCloudletStatusString(cloudlet.getCloudletStatus());
Log.printLine(String.format("%-11d | %-11d | %-10s | %-10s | %-10s",
cloudlet.getCloudletId(),
cloudlet.getContainerId(),
status,
dft.format(cloudlet.getExecStartTime()),
cloudlet.getFinishTime() > 0 ? dft.format(cloudlet.getFinishTime()) : "Running"
));
}
}
private static String getCloudletStatusString(int status) {
switch (status) {
case ContainerCloudlet.CREATED:
return "CREATED";
case ContainerCloudlet.READY:
return "READY";
case ContainerCloudlet.INEXEC:
return "EXECUTING";
case ContainerCloudlet.SUCCESS:
return "SUCCESS";
case ContainerCloudlet.FAILED:
return "FAILED";
default:
return "UNKNOWN";
}
}
private static EnhancedContainerDatacenterBroker createEnhancedBroker(int overBookingFactor) {
EnhancedContainerDatacenterBroker broker = null;
try {
broker = new EnhancedContainerDatacenterBroker("MigrationBroker", overBookingFactor);
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
return broker;
}
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();
}
private static void printCloudletList(List list) {
Log.printLine("\n FINAL RESULTS ==========");
Log.printLine("Cloudlet ID | Container ID | Status | DC ID | VM ID | Time | Start Time | Finish Time");
Log.printLine("------------|-------------|---------|-------|-------|--------|------------|------------");
DecimalFormat dft = new DecimalFormat("###.##");
for (ContainerCloudlet cloudlet : list) {
if (cloudlet.getCloudletStatusString().equals("Success")) {
Log.printLine(String.format("%-11d | %-11d | %-7s | %-5d | %-5d | %-6s | %-10s | %-11s",
cloudlet.getCloudletId(),
cloudlet.getContainerId(),
"SUCCESS",
cloudlet.getResourceId(),
cloudlet.getVmId(),
dft.format(cloudlet.getActualCPUTime()),
dft.format(cloudlet.getExecStartTime()),
dft.format(cloudlet.getFinishTime())
));
}
}
}
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;
}
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;
}
public static ContainerDatacenter createDatacenter(String name, Class< extends ContainerDatacenter> datacenterClass,
List hostList, ContainerVmAllocationPolicy vmAllocationPolicy,
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;
ContainerDatacenterCharacteristics characteristics = new ContainerDatacenterCharacteristics(
arch, os, vmm, hostList, time_zone, cost, costPerMem, costPerStorage, costPerBw);
ContainerDatacenter datacenter = new PowerContainerDatacenterCM(name, characteristics, vmAllocationPolicy,
containerAllocationPolicy, new LinkedList(), schedulingInterval, experimentName, logAddress,
VMStartupDelay, ContainerStartupDelay);
return datacenter;
}
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;
}
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;
for (java.io.File aFiles1 : files1) {
java.io.File inputFolder = new java.io.File(aFiles1.toString());
java.io.File[] files = inputFolder.listFiles();
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 e) {
e.printStackTrace();
System.exit(0);
}
cloudlet.setUserId(brokerId);
cloudletList.add(cloudlet);
createdCloudlets += 1;
} else {
return cloudletList;
}
}
}
return cloudletList;
}
}
2. SourceCode2:
package ContainerMigration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.cloudbus.cloudsim.Log;
import org.cloudbus.cloudsim.container.core.Container;
import org.cloudbus.cloudsim.container.core.ContainerCloudlet;
import org.cloudbus.cloudsim.container.core.ContainerDatacenterBroker;
import org.cloudbus.cloudsim.core.CloudSim;
public class EnhancedContainerDatacenterBroker extends ContainerDatacenterBroker {
private Map migrationQueue = new HashMap<>();
private final List submittedContainers = new ArrayList<>();
public EnhancedContainerDatacenterBroker(String name, int overBookingFactor) throws Exception {
super(name, overBookingFactor);
}
/**
* Request cloudlet migration between containers
*/
public boolean migrateCloudlet(int cloudletId, int sourceContainerId,
int destinationContainerId, double delay) {
double migrationTime = CloudSim.clock() + delay;
MigrationRequest request = new MigrationRequest(cloudletId, sourceContainerId,
destinationContainerId, migrationTime);
migrationQueue.put(cloudletId, request);
Log.printLine(String.format(
" MIGRATION SCHEDULED: Cloudlet %d from Container %d to Container %d at time ~%.2f",
cloudletId, sourceContainerId, destinationContainerId, migrationTime));
return true;
}
/**
* Execute pending migrations
*/
public void executeMigrations() {
double currentTime = CloudSim.clock();
Iterator> iterator = migrationQueue.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = iterator.next();
MigrationRequest request = entry.getValue();
if (request.getScheduledTime() <= currentTime) {
if (executeSingleMigration(request)) {
iterator.remove();
}
}
}
}
private boolean executeSingleMigration(MigrationRequest request) {
ContainerCloudlet cloudlet = findCloudletById(request.getCloudletId());
Container sourceContainer = findContainerById(request.getSourceContainerId());
Container destinationContainer = findContainerById(request.getDestinationContainerId());
if (cloudlet == null || sourceContainer == null || destinationContainer == null) {
Log.printLine(" MIGRATION FAILED: One or more entities not found");
return false;
}
if (cloudlet.getContainerId() != request.getSourceContainerId()) {
Log.printLine(" MIGRATION FAILED: Cloudlet not in specified source container");
return false;
}
// Check if cloudlet is still executing
if (cloudlet.getCloudletStatus() != ContainerCloudlet.INEXEC) {
Log.printLine(" MIGRATION FAILED: Cloudlet is not in execution state");
return false;
}
// Perform migration
int oldContainerId = cloudlet.getContainerId();
cloudlet.setContainerId(request.getDestinationContainerId());
Log.printLine(String.format(
" MIGRATION SUCCESSFUL: Cloudlet %d moved from Container %d to Container %d at time %.2f",
request.getCloudletId(), oldContainerId, request.getDestinationContainerId(), CloudSim.clock()));
// Print current status of all cloudlets after migration
//printCloudletStatus("After Migration");
return true;
}
private ContainerCloudlet findCloudletById(int cloudletId) {
for (ContainerCloudlet cloudlet : getCloudletSubmittedList()) {
if (cloudlet.getCloudletId() == cloudletId) {
return cloudlet;
}
}
return null;
}
private Container findContainerById(int containerId) {
for (Container container : getContainersSubmittedList()) {
if (container.getId() == containerId) {
return container;
}
}
return null;
}
public void submitContainerList(List< extends Container> list) {
super.submitContainerList(list);
submittedContainers.addAll((List) list);
}
public List getContainersSubmittedList() {
return submittedContainers;
}
@Override
public void processEvent(org.cloudbus.cloudsim.core.SimEvent ev) {
super.processEvent(ev);
// Process migrations every 100 time units
if (CloudSim.clock() % 100 == 0) {
executeMigrations();
}
}
/**
* Migration Request Data Structure
*/
private static class MigrationRequest {
private int cloudletId;
private int sourceContainerId;
private int destinationContainerId;
private double scheduledTime;
public MigrationRequest(int cloudletId, int sourceContainerId,
int destinationContainerId, double scheduledTime) {
this.cloudletId = cloudletId;
this.sourceContainerId = sourceContainerId;
this.destinationContainerId = destinationContainerId;
this.scheduledTime = scheduledTime;
}
public int getCloudletId() {
return cloudletId;
}
public int getSourceContainerId() {
return sourceContainerId;
}
public int getDestinationContainerId() {
return destinationContainerId;
}
public double getScheduledTime() {
return scheduledTime;
}
}
}