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

Reply via email to