Container Scheduler
The "ContainerScheduler" class is responsible for allocating suitable "vHost" instances to "vContainer" instances based on the available CPU and RAM resources. The scheduling process is implemented as an event that is triggered whenever a new "vContainer" is created or a "vContainer" is terminated. Only one scheduling process can exist at any time during the simulation.
The "ContainerScheduler" class includes an abstract member function called "findHost", which allows developers to customize the conditions for determining which "vHost" instances are eligible for hosting a specific "vContainer". By implementing the "findHost" function, different scheduling strategies can be employed based on specific requirements and constraints.
PyCloudSim provides several default schedulers that can be used with the "ContainerScheduler" class:
- "Bestfit" scheduler: This scheduler finds the most utilized "vHost" instance that still has available resources to host the "vContainer" being scheduled.
- "Worstfit" scheduler: This scheduler finds the most underutilized "vHost" instance that still has available resources to host the "vContainer" being scheduled.
- "Random" scheduler: This scheduler allocates the "vContainer" to a random "vHost" instance that has sufficient resources.
Only one "ContainerScheduler" can be defined and used in the simulation. If multiple "ContainerScheduler" instances are initialized, the last one defined will be used during the simulation.
The general procedure followed by the "ContainerScheduler" involves evaluating the available resources of each "vHost" instance and selecting the most suitable "vHost" to host the "vContainer" based on the defined scheduling strategy. This process ensures efficient resource allocation and utilization in the simulated cloud environment.
ContainerScheduler
Bases: ABC
Source code in PyCloudSim\scheduler\container_scheduler.py
| class ContainerScheduler(ABC):
__host_affinity: bool
def __init__(
self,
host_affinity: bool = False,
) -> None:
"""Base class for container schedulers.
Args:
host_affinity (bool, optional): set to true for host affinity scheduling, that the host and container must have the same taint. Defaults to False.
"""
self._host_affinity = host_affinity
self._active_process: Actor = None # type: ignore
simulation._container_scheduler = self
@abstractmethod
def find_host(self, container: vContainer) -> Union[vHost, None]:
"""Abstract function to be implemented with your specific container scheduling algorithm."""
pass
def schedule(self):
"""Event function to be called by the simulation engine to schedule containers. find_host() is called automatically by this function."""
def _schedule():
self._active_process = None # type: ignore
for container in simulation.CONTAINERS:
if (
container.scheduled
or container.terminated
or not container.schedulable
):
continue
if candidate_host := self.find_host(container):
candidate_host.allocate_container(container)
if not container.scheduled:
LOGGER.info(
f"{simulation.now:0.2f}\tvContainer {container.label} can not be shceduled, privisioning new vHost if possible."
)
if self.host_affinity:
for host in simulation.HOSTS:
if host.taint == container.taint:
simulation.host_privisioner.privision(host)
else:
for host in simulation.HOSTS:
if host.powered_off:
simulation.host_privisioner.privision(host)
if self.active_process is None:
self._active_process = Actor(
at=simulation.now,
action=_schedule,
label=f"vContainer Scheduling",
priority=CONTAINER_SCHEDULER,
)
@property
def host_affinity(self) -> bool:
"""returns True if host affinity is enabled, False otherwise."""
return self._host_affinity
@property
def active_process(self) -> Actor:
"""returns the active process of the scheduler."""
return self._active_process
|
active_process: Actor
property
returns the active process of the scheduler.
host_affinity: bool
property
returns True if host affinity is enabled, False otherwise.
__init__(host_affinity=False)
Base class for container schedulers.
Parameters:
Name |
Type |
Description |
Default |
host_affinity |
bool
|
set to true for host affinity scheduling, that the host and container must have the same taint. Defaults to False.
|
False
|
Source code in PyCloudSim\scheduler\container_scheduler.py
| def __init__(
self,
host_affinity: bool = False,
) -> None:
"""Base class for container schedulers.
Args:
host_affinity (bool, optional): set to true for host affinity scheduling, that the host and container must have the same taint. Defaults to False.
"""
self._host_affinity = host_affinity
self._active_process: Actor = None # type: ignore
simulation._container_scheduler = self
|
find_host(container)
abstractmethod
Abstract function to be implemented with your specific container scheduling algorithm.
Source code in PyCloudSim\scheduler\container_scheduler.py
| @abstractmethod
def find_host(self, container: vContainer) -> Union[vHost, None]:
"""Abstract function to be implemented with your specific container scheduling algorithm."""
pass
|
schedule()
Event function to be called by the simulation engine to schedule containers. find_host() is called automatically by this function.
Source code in PyCloudSim\scheduler\container_scheduler.py
| def schedule(self):
"""Event function to be called by the simulation engine to schedule containers. find_host() is called automatically by this function."""
def _schedule():
self._active_process = None # type: ignore
for container in simulation.CONTAINERS:
if (
container.scheduled
or container.terminated
or not container.schedulable
):
continue
if candidate_host := self.find_host(container):
candidate_host.allocate_container(container)
if not container.scheduled:
LOGGER.info(
f"{simulation.now:0.2f}\tvContainer {container.label} can not be shceduled, privisioning new vHost if possible."
)
if self.host_affinity:
for host in simulation.HOSTS:
if host.taint == container.taint:
simulation.host_privisioner.privision(host)
else:
for host in simulation.HOSTS:
if host.powered_off:
simulation.host_privisioner.privision(host)
if self.active_process is None:
self._active_process = Actor(
at=simulation.now,
action=_schedule,
label=f"vContainer Scheduling",
priority=CONTAINER_SCHEDULER,
)
|
ContainerSchedulerBestfit
Bases: ContainerScheduler
Bestfit container scheduler, that finds the fullest host for the container based on the available resources of the host.
Source code in PyCloudSim\scheduler\container_scheduler.py
| class ContainerSchedulerBestfit(ContainerScheduler):
"""Bestfit container scheduler, that finds the fullest host for the container based on the available resources of the host.
"""
def find_host(self, container: vContainer) -> vHost | None:
if self._host_affinity:
candidate_host = [host for host in simulation.HOSTS if host.taint == container.taint and host.powered_on]
candidate_host.sort(key=lambda host: host.ram.utilization)
candidate_host.sort(key=lambda host: host.cpu.utilization)
for host in candidate_host:
if (
host.cpu_reservor.available_quantity >= container.cpu_request
and host.ram_reservor.available_quantity
>= container.ram_request
and host.rom.available_quantity >= container.image_size
):
LOGGER.debug(
f"{simulation.now:0.2f}\tFound vHost {host.label} {host.cpu.availablity} CPU, {host.ram.available_quantity} RAM, {host.rom.available_quantity} ROM for vContainer {container.label} {container.cpu_request} CPU, {container.ram_request} RAM, {container.image_size} ROM"
)
return host
else:
simulation.HOSTS.sort(key=lambda host: host.ram.utilization)
simulation.HOSTS.sort(key=lambda host: host.cpu.utilization)
for host in simulation.HOSTS:
if host.powered_on:
if (
host.cpu_reservor.available_quantity >= container.cpu_request
and host.ram_reservor.available_quantity
>= container.ram_request
and host.rom.available_quantity >= container.image_size
):
LOGGER.debug(
f"{simulation.now:0.2f}\tFound vHost {host.label} {host.cpu_reservor.available_quantity} CPU, {host.ram_reservor.available_quantity} RAM, {host.rom.available_quantity} ROM for vContainer {container.label} {container.cpu_request} CPU, {container.ram_request} RAM, {container.image_size} ROM"
)
return host
return None
|
ContainerSchedulerRandom
Bases: ContainerScheduler
Worstfit container scheduler, that finds the most empty host for the container based on the available resources of the host.
Source code in PyCloudSim\scheduler\container_scheduler.py
| class ContainerSchedulerRandom(ContainerScheduler):
"""Worstfit container scheduler, that finds the most empty host for the container based on the available resources of the host.
"""
def find_host(self, container: vContainer) -> vHost | None:
if self._host_affinity:
candidate_host = [host for host in simulation.HOSTS if host.taint == container.taint and host.powered_on]
random.shuffle(candidate_host)
for host in candidate_host:
if (
host.cpu_reservor.available_quantity >= container.cpu_request
and host.ram_reservor.available_quantity
>= container.ram_request
and host.rom.available_quantity >= container.image_size
):
LOGGER.debug(
f"{simulation.now:0.2f}\tFound vHost {host.label} {host.cpu.availablity} CPU, {host.ram.available_quantity} RAM, {host.rom.available_quantity} ROM for vContainer {container.label} {container.cpu_request} CPU, {container.ram_request} RAM, {container.image_size} ROM"
)
return host
else:
random.shuffle(simulation.HOSTS)
for host in simulation.HOSTS:
if host.powered_on:
if (
host.cpu_reservor.available_quantity >= container.cpu_request
and host.ram_reservor.available_quantity
>= container.ram_request
and host.rom.available_quantity >= container.image_size
):
LOGGER.debug(
f"{simulation.now:0.2f}\tFound vHost {host.label} {host.cpu_reservor.available_quantity} CPU, {host.ram_reservor.available_quantity} RAM, {host.rom.available_quantity} ROM for vContainer {container.label} {container.cpu_request} CPU, {container.ram_request} RAM, {container.image_size} ROM"
)
return host
return None
|
ContainerSchedulerWorstfit
Bases: ContainerScheduler
Worstfit container scheduler, that finds the most empty host for the container based on the available resources of the host.
Source code in PyCloudSim\scheduler\container_scheduler.py
| class ContainerSchedulerWorstfit(ContainerScheduler):
"""Worstfit container scheduler, that finds the most empty host for the container based on the available resources of the host.
"""
def find_host(self, container: vContainer) -> vHost | None:
if self._host_affinity:
candidate_host = [host for host in simulation.HOSTS if host.taint == container.taint and host.powered_on]
candidate_host.sort(key=lambda host: host.ram.utilization, reverse=True)
candidate_host.sort(key=lambda host: host.cpu.utilization, reverse=True)
for host in candidate_host:
if (
host.cpu_reservor.available_quantity >= container.cpu_request
and host.ram_reservor.available_quantity
>= container.ram_request
and host.rom.available_quantity >= container.image_size
):
LOGGER.debug(
f"{simulation.now:0.2f}\tFound vHost {host.label} {host.cpu.availablity} CPU, {host.ram.available_quantity} RAM, {host.rom.available_quantity} ROM for vContainer {container.label} {container.cpu_request} CPU, {container.ram_request} RAM, {container.image_size} ROM"
)
return host
else:
simulation.HOSTS.sort(key=lambda host: host.ram.utilization, reverse=True)
simulation.HOSTS.sort(key=lambda host: host.cpu.utilization, reverse=True)
for host in simulation.HOSTS:
if host.powered_on:
if (
host.cpu_reservor.available_quantity >= container.cpu_request
and host.ram_reservor.available_quantity
>= container.ram_request
and host.rom.available_quantity >= container.image_size
):
LOGGER.debug(
f"{simulation.now:0.2f}\tFound vHost {host.label} {host.cpu_reservor.available_quantity} CPU, {host.ram_reservor.available_quantity} RAM, {host.rom.available_quantity} ROM for vContainer {container.label} {container.cpu_request} CPU, {container.ram_request} RAM, {container.image_size} ROM"
)
return host
return None
|