All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cloudsimplus.autoscaling.VerticalVmScaling Maven / Gradle / Ivy

Go to download

CloudSim Plus: A modern, highly extensible and easier-to-use Java 8+ Framework for Modeling and Simulation of Cloud Computing Infrastructures and Services

There is a newer version: 8.0.0
Show newest version
/*
 * CloudSim Plus: A modern, highly-extensible and easier-to-use Framework for
 * Modeling and Simulation of Cloud Computing Infrastructures and Services.
 * http://cloudsimplus.org
 *
 *     Copyright (C) 2015-2021 Universidade da Beira Interior (UBI, Portugal) and
 *     the Instituto Federal de Educação Ciência e Tecnologia do Tocantins (IFTO, Brazil).
 *
 *     This file is part of CloudSim Plus.
 *
 *     CloudSim Plus is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     CloudSim Plus is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with CloudSim Plus. If not, see .
 */
package org.cloudsimplus.autoscaling;

import org.cloudbus.cloudsim.allocationpolicies.VmAllocationPolicy;
import org.cloudbus.cloudsim.brokers.DatacenterBroker;
import org.cloudbus.cloudsim.cloudlets.Cloudlet;
import org.cloudbus.cloudsim.datacenters.Datacenter;
import org.cloudbus.cloudsim.resources.*;
import org.cloudbus.cloudsim.utilizationmodels.UtilizationModel;
import org.cloudbus.cloudsim.vms.Vm;
import org.cloudsimplus.autoscaling.resources.ResourceScaling;
import org.cloudsimplus.listeners.EventListener;
import org.cloudsimplus.listeners.VmHostEventInfo;

import java.util.function.Function;

import static org.cloudbus.cloudsim.utilizationmodels.UtilizationModel.Unit;

/**
 * A Vm Vertical Scaling
 * mechanism used by a {@link DatacenterBroker} to request the dynamic scale of
 * VM resources up or down, according to the current resource usage.
 * For each resource supposed to be scaled, a different {@code VerticalVmScaling}
 * instance should be provided.
 * If a scaling object is going to be set to a Vm, it has to be exclusive of that Vm.
 * Different Vms must have different instances of a scaling object.
 *
 * 

A {@link Vm} runs a set of {@link Cloudlet}s. When a {@code VerticalVmScaling} object * is attached to a {@link Vm}, it's required to define which * {@link #getResourceClass() resource will be scaled} ({@link Ram}, {@link Bandwidth}, etc) * when it's {@link #getLowerThresholdFunction() under} or * {@link #getUpperThresholdFunction() overloaded}. *

* *

* The scaling request follows this path: *

    *
  • a {@link Vm} that has a {@link VerticalVmScaling} object set monitors its own * resource usage using an {@link EventListener}, to check if an * {@link #getLowerThresholdFunction() under} or * {@link #getUpperThresholdFunction() overload} condition is met;
  • *
  • if any of these conditions is met, the Vm uses the VerticalVmScaling * to send a scaling request to its {@link DatacenterBroker};
  • *
  • the DatacenterBroker forwards the request to the {@link Datacenter} * where the Vm is hosted;
  • *
  • the Datacenter delegates the task to its {@link VmAllocationPolicy};
  • *
  • the VmAllocationPolicy checks if there is resource availability and then * finally scale the Vm.
  • *
*

* *

WARNING

*
* Make sure that the {@link UtilizationModel} of some of these {@code Cloudlets} * is defined as {@link Unit#ABSOLUTE ABSOLUTE}. Defining the {@code UtilizationModel} * of all {@code Cloudlets} running inside the {@code Vm} as {@link Unit#PERCENTAGE PERCENTAGE} * causes these {@code Cloudlets} to automatically increase/decrease their resource usage when the * {@code Vm} resource is vertically scaled. * This is not a CloudSim Plus issue, but the natural and maybe * surprising effect that may trap researchers trying to implement and assess VM scaling policies. * *

Consider the following example: a {@code VerticalVmScaling} is attached to * a {@code Vm} to double its {@link Ram} when its usage reaches 50%. * The {@code Vm} has 10GB of RAM. * All {@code Cloudlets} running inside this {@code Vm} have a {@link UtilizationModel} * for their RAM utilization define in {@link Unit#PERCENTAGE PERCENTAGE}. * When the RAM utilization of all these * {@code Cloudlets} reach the 50% (5GB), the {@code Vm} {@link Ram} will be doubled. * However, as the RAM usage of the running {@code Cloudlets} is defined in percentage, they will * continue to use 50% of {@code Vm}'s RAM, that now represents 10GB from the 20GB capacity. * This way, the vertical scaling will have no real benefit.

* * @author Manoel Campos da Silva Filho * @since CloudSim Plus 1.1.0 */ public interface VerticalVmScaling extends VmScaling { /** * An attribute that implements the Null Object Design Pattern for {@link VerticalVmScaling} * objects. */ VerticalVmScaling NULL = new VerticalVmScalingNull(); /** * Gets the class of Vm resource this scaling object will request up or down scaling. * Such a class can be {@link Ram}.class, {@link Bandwidth}.class or {@link Pe}.class. * @return * @see #getResource() */ Class getResourceClass(); /** * Gets the factor that will be used to scale a Vm resource up or down, * whether such a resource is over or underloaded, according to the * defined predicates. * *

If the resource to scale is a {@link Pe}, this is the number of PEs * to request adding or removing when the VM is over or underloaded, respectively. * For any other kind of resource, this is a percentage value in scale from 0 to 1. * Every time the VM needs to be scaled up or down, this factor will be applied * to increase or reduce a specific VM allocated resource.

* * @return the scaling factor to set which may be an absolute value (for {@link Pe} scaling) * or percentage (for scaling other resources) * @see #getUpperThresholdFunction() */ double getScalingFactor(); /** * Sets the factor that will be used to scale a Vm resource up or down, * whether such a resource is over or underloaded, according to the * defined predicates. * *

If the resource to scale is a {@link Pe}, this is the number of PEs * to request adding or removing when the VM is over or underloaded, respectively. * For any other kind of resource, this is a percentage value in scale from 0 to 1. * Every time the VM needs to be scaled up or down, this factor will be applied * to increase or reduce a specific VM allocated resource.

* * @param scalingFactor the scaling factor to set which may be an absolute value * (for {@link Pe} scaling) or percentage (for scaling other resources) * @see #getUpperThresholdFunction() */ VerticalVmScaling setScalingFactor(double scalingFactor); /** * Gets the lower or upper resource utilization threshold {@link Function}, * depending if the Vm resource is under or overloaded, respectively. * * @return the lower resource utilization threshold function if the Vm resource * is underloaded, upper resource utilization threshold function if the Vm resource * is overloaded, or a function that always returns 0 if the Vm isn't in any of these conditions. * @see #getLowerThresholdFunction() * @see #getUpperThresholdFunction() */ Function getResourceUsageThresholdFunction(); /** * Checks if the Vm is underloaded or not, based on the * {@link #getLowerThresholdFunction()}. * @return true if the Vm is underloaded, false otherwise */ boolean isVmUnderloaded(); /** * Checks if the Vm is overloaded or not, based on the * {@link #getUpperThresholdFunction()}. * @return true if the Vm is overloaded, false otherwise */ boolean isVmOverloaded(); /** * Gets the actual Vm {@link Resource} this scaling object is in charge of scaling. * @return */ Resource getResource(); /** * Gets the absolute amount of the Vm resource which has to be * scaled up or down, based on the {@link #getScalingFactor() scaling factor}. * * @return the absolute amount of the Vm resource to scale * @see #getResourceClass() */ double getResourceAmountToScale(); /** * Performs the vertical scale if the Vm is overloaded, according to the * {@link #getUpperThresholdFunction()} predicate, * increasing the Vm resource to which the scaling object is linked to * (that may be RAM, CPU, BW, etc.), by the factor defined a scaling factor. * *

The time interval in which it will be checked if the Vm is overloaded * depends on the {@link Datacenter#getSchedulingInterval()} value. * Make sure to set such a value to enable the periodic overload verification.

* * @param evt current simulation time * @see #getScalingFactor() */ @Override boolean requestUpScalingIfPredicateMatches(VmHostEventInfo evt); /** * Gets a {@link Function} that defines the upper utilization threshold for a {@link #getVm() Vm} * which indicates if it is overloaded or not. * If it is overloaded, the Vm's {@link DatacenterBroker} will request to up scale the VM. * The up scaling is performed by increasing the amount of the {@link #getResourceClass() resource} * the scaling is associated to. * *

This function must receive a {@link Vm} and return the upper utilization threshold * for it as a percentage value between 0 and 1 (where 1 is 100%). * The VM will be defined as overloaded if the utilization of the {@link Resource} * this scaling object is related to is higher than the value returned by the {@link Function} * returned by this method.

* * @return * @see #setUpperThresholdFunction(Function) */ Function getUpperThresholdFunction(); /** * Sets a {@link Function} that defines the upper utilization threshold for a {@link #getVm() Vm} * which indicates if it is overloaded or not. * If it is overloaded, the Vm's {@link DatacenterBroker} will request to up scale the VM. * The up scaling is performed by increasing the amount of the * {@link #getResourceClass() resource} the scaling is associated to. * *

This function must receive a {@link Vm} and return the upper utilization threshold * for it as a percentage value between 0 and 1 (where 1 is 100%).

* *

By setting the upper threshold as a {@link Function} instead of a directly * storing a {@link Double} value which represent the threshold, it is possible * to define the threshold dynamically instead of using a static value. * Furthermore, the threshold function can be reused for scaling objects of * different VMs.

* * @param upperThresholdFunction the upper utilization threshold function to set. * The VM will be defined as overloaded if the utilization of the {@link Resource} * this scaling object is related to is higher than the value returned by this {@link Function}. * @return */ VerticalVmScaling setUpperThresholdFunction(Function upperThresholdFunction); /** * Gets a {@link Function} that defines the lower utilization threshold for a {@link #getVm() Vm} * which indicates if it is underloaded or not. * If it is underloaded, the Vm's {@link DatacenterBroker} will request to down scale the VM. * The down scaling is performed by decreasing the amount of the * {@link #getResourceClass() resource} the scaling is associated to. * *

This function must receive a {@link Vm} and return the lower utilization threshold * for it as a percentage value between 0 and 1 (where 1 is 100%). * * The VM will be defined as underloaded if the utilization of the {@link Resource} * this scaling object is related to is lower than the value returned by the {@link Function} * returned by this method.

* * @return * @see #setLowerThresholdFunction(Function) */ Function getLowerThresholdFunction(); /** * Sets a {@link Function} that defines the lower utilization threshold for a {@link #getVm() Vm} * which indicates if it is underloaded or not. * If it is underloaded, the Vm's {@link DatacenterBroker} will request to down scale the VM. * The down scaling is performed by decreasing the amount of the * {@link #getResourceClass() resource} the scaling is associated to. * *

This function must receive a {@link Vm} and return the lower utilization threshold * for it as a percentage value between 0 and 1 (where 1 is 100%).

* *

By setting the lower threshold as a {@link Function} instead of a directly * storing a {@link Double} value which represent the threshold, it is possible * to define the threshold dynamically instead of using a static value. * Furthermore, the threshold function can be reused for scaling objects of * different VMs.

* * @param lowerThresholdFunction the lower utilization threshold function to set. * The VM will be defined as underloaded if the utilization of the {@link Resource} * this scaling object is related to is lower than the value returned by this {@link Function}. * @return */ VerticalVmScaling setLowerThresholdFunction(Function lowerThresholdFunction); /** * Sets the {@link ResourceScaling} that defines how the resource has to be resized. * @param resourceScaling the {@link ResourceScaling} to set * @return */ VerticalVmScaling setResourceScaling(ResourceScaling resourceScaling); /** * Gets the current amount allocated to the {@link #getResource() resource} * managed by this scaling object. * It is just a shortcut to {@code getVmResourceToScale.getAllocatedResource()}. * @return the amount of allocated resource */ long getAllocatedResource(); /** * Tries to allocate more resources for a VM, * if there is availability. * @return */ boolean allocateResourceForVm(); void logResourceUnavailable(); void logDownscaleToZeroNotAllowed(); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy