Gilad Chaplik has uploaded a new change for review. Change subject: core: loadbalancing: prevent VM bounces between hosts ......................................................................
core: loadbalancing: prevent VM bounces between hosts When balancing a cluster, the balancing logic should return a VM and acceptable hosts, while filtering those hosts the scheduler#balance doesn't take into account the predicted VM CPU load. This may result in a VM bouncing between 2 hosts (if VM consumes all the CPU resources on both hosts). Change-Id: I6beebf4324bfa5218d9617619b350fb9a2de56d3 Bug-Url: https://bugzilla.redhat.com/1043233 Signed-off-by: Gilad Chaplik <gchap...@redhat.com> --- M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenDistributionBalancePolicyUnit.java 1 file changed, 39 insertions(+), 6 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/54/22454/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenDistributionBalancePolicyUnit.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenDistributionBalancePolicyUnit.java index 1e42831..d3d93bb 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenDistributionBalancePolicyUnit.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenDistributionBalancePolicyUnit.java @@ -29,12 +29,14 @@ public class EvenDistributionBalancePolicyUnit extends PolicyUnitImpl { + private static final String HIGH_UTILIZATION = "HighUtilization"; + public EvenDistributionBalancePolicyUnit(PolicyUnit policyUnit) { super(policyUnit); } @Override - public Pair<List<Guid>, Guid> balance(VDSGroup cluster, + public Pair<List<Guid>, Guid> balance(final VDSGroup cluster, List<VDS> hosts, Map<String, String> parameters, ArrayList<String> messages) { @@ -58,7 +60,22 @@ if(migrableVmsOnRandomHost.isEmpty()) { return null; } - VM vm = getBestVmToMigrate(randomHost.getId(), migrableVmsOnRandomHost); + final VM vm = getBestVmToMigrate(randomHost.getId(), migrableVmsOnRandomHost); + + // check that underutilized host's CPU + predicted VM cpu is less than threshold, + // to prevent the VM to be bounced between hosts. + final int highUtilization = tryParseWithDefault(parameters.get(HIGH_UTILIZATION), + getHighUtilizationDefaultValue()); + underUtilizedHosts = LinqUtils.filter(underUtilizedHosts, new Predicate<VDS>() { + @Override + public boolean eval(VDS vds) { + int predictedVmCpu = getPredictedVmCpu(vm, vds, cluster.getCountThreadsAsCores()); + return vds.getUsageCpuPercent() + predictedVmCpu <= highUtilization; + } + }); + if (underUtilizedHosts.size() == 0) { + return null; + } List<Guid> underUtilizedHostsKeys = new ArrayList<Guid>(); for (VDS vds : underUtilizedHosts) { @@ -85,9 +102,10 @@ if (result == null) { log.info("VdsLoadBalancer: vm selection - no vm without pending found."); result = Collections.min(vms, new VmCpuUsageComparator()); + } else { + log.infoFormat("VdsLoadBalancer: vm selection - selected vm: {0}, cpu: {1}.", result.getName(), + result.getUsageCpuPercent()); } - log.infoFormat("VdsLoadBalancer: vm selection - selected vm: {0}, cpu: {1}.", result.getName(), - result.getUsageCpuPercent()); return result; } @@ -106,7 +124,7 @@ protected List<VDS> getOverUtilizedHosts(List<VDS> relevantHosts, Map<String, String> parameters) { - final int highUtilization = tryParseWithDefault(parameters.get("HighUtilization"), + final int highUtilization = tryParseWithDefault(parameters.get(HIGH_UTILIZATION), getHighUtilizationDefaultValue()); final int cpuOverCommitDurationMinutes = tryParseWithDefault(parameters.get("CpuOverCommitDurationMinutes"), Config @@ -131,7 +149,7 @@ protected List<VDS> getUnderUtilizedHosts(VDSGroup cluster, List<VDS> relevantHosts, Map<String, String> parameters) { - int highUtilization = tryParseWithDefault(parameters.get("HighUtilization"), Config + int highUtilization = tryParseWithDefault(parameters.get(HIGH_UTILIZATION), Config .<Integer> getValue(ConfigValues.HighUtilizationForEvenlyDistribute)); final int highVdsCount = Math .min(Config.<Integer> getValue(ConfigValues.UtilizationThresholdInPercent) @@ -200,4 +218,19 @@ } return defaultValue; } + + /** + * The predicted CPU the CPU that the VM will take considering + * how many cores it has and how many cores the host has. + * @return + * predicted vm cpu + */ + protected int getPredictedVmCpu(VM vm, VDS vds, boolean countThreadsAsCores) { + Integer effectiveCpuCores = SlaValidator.getEffectiveCpuCores(vds, countThreadsAsCores); + if (vm.getUsageCpuPercent() != null && effectiveCpuCores != null) { + return (vm.getUsageCpuPercent() * vm.getNumOfCpus()) + / effectiveCpuCores; + } + return 0; + } } -- To view, visit http://gerrit.ovirt.org/22454 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6beebf4324bfa5218d9617619b350fb9a2de56d3 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Gilad Chaplik <gchap...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches