Search in sources :

Example 1 with BalanceResult

use of org.ovirt.engine.core.bll.scheduling.external.BalanceResult in project ovirt-engine by oVirt.

the class HaReservationBalancePolicyUnit method balance.

@Override
public Optional<BalanceResult> balance(Cluster cluster, List<VDS> hosts, Map<String, String> parameters, ArrayList<String> messages) {
    Objects.requireNonNull(hosts);
    Objects.requireNonNull(cluster);
    log.debug("Started HA reservation balancing method for cluster '{}'", cluster.getName());
    if (!cluster.supportsHaReservation()) {
        return Optional.empty();
    }
    if (hosts.size() < 2) {
        log.debug("No balancing for cluster '{}', contains only {} host(s)", cluster.getName(), hosts.size());
        return Optional.empty();
    }
    int haVmsInCluster = 0;
    Map<Guid, List<VM>> hostId2HaVmMapping = HaReservationHandling.mapHaVmToHostByCluster(cluster.getId());
    haVmsInCluster = countHaVmsInCluster(hostId2HaVmMapping);
    int optimalHaDistribution = (int) Math.ceil((double) haVmsInCluster / hosts.size());
    int overUtilizationParam = DEFAULT_OVER_UTILIZATION_VALUE;
    if (parameters.get("OverUtilization") != null) {
        overUtilizationParam = NumberUtils.toInt(parameters.get("OverUtilization"));
    } else {
        overUtilizationParam = Config.<Integer>getValue(ConfigValues.OverUtilizationForHaReservation);
    }
    log.debug("optimalHaDistribution value: {}", optimalHaDistribution);
    int overUtilizationThreshold = (int) Math.ceil(optimalHaDistribution * (overUtilizationParam / 100.0));
    log.debug("overUtilizationThreshold value: {}", overUtilizationThreshold);
    List<VDS> overUtilizedHosts = getHostUtilizedByCondition(hosts, hostId2HaVmMapping, overUtilizationThreshold, Condition.MORE_THAN);
    if (overUtilizedHosts.isEmpty()) {
        log.debug("No over utilized hosts for cluster '{}'", cluster.getName());
        return Optional.empty();
    }
    List<VDS> underUtilizedHosts = getHostUtilizedByCondition(hosts, hostId2HaVmMapping, overUtilizationParam, Condition.LESS_THAN);
    if (underUtilizedHosts.size() == 0) {
        log.debug("No under utilized hosts for cluster '{}'", cluster.getName());
        return Optional.empty();
    }
    // Get random host from the over utilized hosts
    VDS randomHost = overUtilizedHosts.get(new Random().nextInt(overUtilizedHosts.size()));
    List<VM> migrableVmsOnRandomHost = getMigrableVmsRunningOnVds(randomHost.getId(), hostId2HaVmMapping);
    if (migrableVmsOnRandomHost.isEmpty()) {
        log.debug("No migratable hosts were found for cluster '{}'", cluster.getName());
        return Optional.empty();
    }
    // Get random vm to migrate
    VM vm = migrableVmsOnRandomHost.get(new Random().nextInt(migrableVmsOnRandomHost.size()));
    log.info("VM to be migrated '{}'", vm.getName());
    List<Guid> underUtilizedHostsKeys = new ArrayList<>();
    for (VDS vds : underUtilizedHosts) {
        underUtilizedHostsKeys.add(vds.getId());
    }
    return Optional.of(new BalanceResult(vm.getId(), underUtilizedHostsKeys));
}
Also used : BalanceResult(org.ovirt.engine.core.bll.scheduling.external.BalanceResult) VDS(org.ovirt.engine.core.common.businessentities.VDS) Random(java.util.Random) VM(org.ovirt.engine.core.common.businessentities.VM) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) Guid(org.ovirt.engine.core.compat.Guid)

Example 2 with BalanceResult

use of org.ovirt.engine.core.bll.scheduling.external.BalanceResult in project ovirt-engine by oVirt.

the class SchedulingManager method externalRunBalance.

private Optional<BalanceResult> externalRunBalance(PolicyUnitImpl policyUnit, Cluster cluster, List<VDS> hosts) {
    List<Guid> hostIDs = new ArrayList<>();
    for (VDS vds : hosts) {
        hostIDs.add(vds.getId());
    }
    Optional<BalanceResult> balanceResult = externalBroker.runBalance(policyUnit.getPolicyUnit().getName(), hostIDs, cluster.getClusterPolicyProperties());
    if (balanceResult.isPresent()) {
        return balanceResult;
    }
    log.warn("All external schedulers returned empty balancing result.");
    return Optional.empty();
}
Also used : BalanceResult(org.ovirt.engine.core.bll.scheduling.external.BalanceResult) VDS(org.ovirt.engine.core.common.businessentities.VDS) ArrayList(java.util.ArrayList) Guid(org.ovirt.engine.core.compat.Guid)

Example 3 with BalanceResult

use of org.ovirt.engine.core.bll.scheduling.external.BalanceResult in project ovirt-engine by oVirt.

the class SchedulingManager method performLoadBalancingImpl.

private void performLoadBalancingImpl() {
    log.debug("Load Balancer timer entered.");
    List<Cluster> clusters = clusterDao.getAll();
    for (Cluster cluster : clusters) {
        ClusterPolicy policy = policyMap.get(cluster.getClusterPolicyId());
        PolicyUnitImpl policyUnit = policyUnits.get(policy.getBalance());
        Optional<BalanceResult> balanceResult = Optional.empty();
        if (policyUnit.getPolicyUnit().isEnabled()) {
            List<VDS> hosts = vdsDao.getAllForClusterWithoutMigrating(cluster.getId());
            if (policyUnit.getPolicyUnit().isInternal()) {
                balanceResult = internalRunBalance(policyUnit, cluster, hosts);
            } else if (Config.<Boolean>getValue(ConfigValues.ExternalSchedulerEnabled)) {
                balanceResult = externalRunBalance(policyUnit, cluster, hosts);
            }
        }
        if (balanceResult.isPresent() && balanceResult.get().isValid()) {
            migrationHandler.migrateVM(balanceResult.get().getCandidateHosts(), balanceResult.get().getVmToMigrate(), MessageBundler.getMessage(AuditLogType.MIGRATION_REASON_LOAD_BALANCING));
        }
    }
}
Also used : BalanceResult(org.ovirt.engine.core.bll.scheduling.external.BalanceResult) VDS(org.ovirt.engine.core.common.businessentities.VDS) Cluster(org.ovirt.engine.core.common.businessentities.Cluster) ClusterPolicy(org.ovirt.engine.core.common.scheduling.ClusterPolicy)

Example 4 with BalanceResult

use of org.ovirt.engine.core.bll.scheduling.external.BalanceResult in project ovirt-engine by oVirt.

the class CpuAndMemoryBalancingPolicyUnit method balance.

@Override
public Optional<BalanceResult> balance(final Cluster cluster, List<VDS> hosts, Map<String, String> parameters, ArrayList<String> messages) {
    Objects.requireNonNull(hosts);
    Objects.requireNonNull(cluster);
    if (hosts.size() < 2) {
        log.debug("No balancing for cluster '{}', contains only {} host(s)", cluster.getName(), hosts.size());
        return Optional.empty();
    }
    final List<VDS> overUtilizedPrimaryHosts = getPrimarySources(cluster, hosts, parameters);
    final List<VDS> overUtilizedSecondaryHosts = getSecondarySources(cluster, hosts, parameters);
    // if there aren't any overutilized hosts, then there is nothing to balance...
    if ((overUtilizedPrimaryHosts == null || overUtilizedPrimaryHosts.size() == 0) && (overUtilizedSecondaryHosts == null || overUtilizedSecondaryHosts.size() == 0)) {
        log.debug("There is no over-utilized host in cluster '{}'", cluster.getName());
        return Optional.empty();
    }
    FindVmAndDestinations findVmAndDestinations = getFindVmAndDestinations(cluster, parameters);
    Optional<BalanceResult> result = Optional.empty();
    // try balancing based on CPU first
    if (overUtilizedPrimaryHosts != null && overUtilizedPrimaryHosts.size() > 0) {
        // returns hosts with utilization lower than the specified threshold
        List<VDS> underUtilizedHosts = getPrimaryDestinations(cluster, hosts, parameters);
        /* if no host has a spare power, then there is nothing we can do to balance it here, try
               the secondary aporoach */
        if (underUtilizedHosts == null || underUtilizedHosts.size() == 0) {
            log.warn("All candidate hosts have been filtered, can't balance the cluster '{}'" + " based on the CPU usage, will try memory based approach", cluster.getName());
        } else {
            result = getBalance(findVmAndDestinations, overUtilizedPrimaryHosts, underUtilizedHosts);
        }
    }
    // if it is not possible (or necessary) to balance based on CPU, try with memory
    if (!result.isPresent() && (overUtilizedSecondaryHosts != null && overUtilizedSecondaryHosts.size() > 0)) {
        // returns hosts with more free memory than the specified threshold
        List<VDS> underUtilizedHosts = getSecondaryDestinations(cluster, hosts, parameters);
        // if no host has memory to spare, then there is nothing we can do to balance it..
        if (underUtilizedHosts == null || underUtilizedHosts.size() == 0) {
            log.warn("All candidate hosts have been filtered, can't balance the cluster '{}'" + " using memory based approach", cluster.getName());
            return Optional.empty();
        }
        result = getBalance(findVmAndDestinations, overUtilizedSecondaryHosts, underUtilizedHosts);
    }
    // add the current host, it is possible it is the best host after all,
    // because the balancer does not know about affinity for example
    Optional<BalanceResult> finalResult = result;
    result.map(BalanceResult::getCurrentHost).filter(Objects::nonNull).ifPresent(h -> finalResult.ifPresent(res -> res.getCandidateHosts().add(h)));
    return result;
}
Also used : VmStatisticsDao(org.ovirt.engine.core.dao.VmStatisticsDao) ClusterDao(org.ovirt.engine.core.dao.ClusterDao) FindVmAndDestinations(org.ovirt.engine.core.bll.scheduling.utils.FindVmAndDestinations) PolicyUnitImpl(org.ovirt.engine.core.bll.scheduling.PolicyUnitImpl) Date(java.util.Date) VdsCpuUsageComparator(org.ovirt.engine.core.bll.scheduling.utils.VdsCpuUsageComparator) LoggerFactory(org.slf4j.LoggerFactory) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Inject(javax.inject.Inject) VdsDao(org.ovirt.engine.core.dao.VdsDao) Map(java.util.Map) PolicyUnitParameter(org.ovirt.engine.core.bll.scheduling.PolicyUnitParameter) Config(org.ovirt.engine.core.common.config.Config) Logger(org.slf4j.Logger) Collection(java.util.Collection) Set(java.util.Set) ConfigValues(org.ovirt.engine.core.common.config.ConfigValues) Collectors(java.util.stream.Collectors) VdsSpmStatus(org.ovirt.engine.core.common.businessentities.VdsSpmStatus) VmDao(org.ovirt.engine.core.dao.VmDao) Objects(java.util.Objects) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) Cluster(org.ovirt.engine.core.common.businessentities.Cluster) PolicyUnit(org.ovirt.engine.core.common.scheduling.PolicyUnit) PendingResourceManager(org.ovirt.engine.core.bll.scheduling.pending.PendingResourceManager) Optional(java.util.Optional) BalanceResult(org.ovirt.engine.core.bll.scheduling.external.BalanceResult) SlaValidator(org.ovirt.engine.core.bll.scheduling.SlaValidator) Collections(java.util.Collections) VDS(org.ovirt.engine.core.common.businessentities.VDS) BalanceResult(org.ovirt.engine.core.bll.scheduling.external.BalanceResult) VDS(org.ovirt.engine.core.common.businessentities.VDS) FindVmAndDestinations(org.ovirt.engine.core.bll.scheduling.utils.FindVmAndDestinations)

Aggregations

BalanceResult (org.ovirt.engine.core.bll.scheduling.external.BalanceResult)4 VDS (org.ovirt.engine.core.common.businessentities.VDS)4 ArrayList (java.util.ArrayList)3 List (java.util.List)2 Cluster (org.ovirt.engine.core.common.businessentities.Cluster)2 Guid (org.ovirt.engine.core.compat.Guid)2 Collection (java.util.Collection)1 Collections (java.util.Collections)1 Date (java.util.Date)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1 Objects (java.util.Objects)1 Optional (java.util.Optional)1 Random (java.util.Random)1 Set (java.util.Set)1 TimeUnit (java.util.concurrent.TimeUnit)1 Collectors (java.util.stream.Collectors)1 Inject (javax.inject.Inject)1 PolicyUnitImpl (org.ovirt.engine.core.bll.scheduling.PolicyUnitImpl)1 PolicyUnitParameter (org.ovirt.engine.core.bll.scheduling.PolicyUnitParameter)1