Jiří Moskovčák has uploaded a new change for review. Change subject: initial implementation of EvenGuestDistribution ......................................................................
initial implementation of EvenGuestDistribution Change-Id: I2f2036dfc8a410c787a195d7d56ac3ed4ace81a7 Signed-off-by: Jiri Moskovcak <[email protected]> --- M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/PolicyUnitImpl.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenDistributionBalancePolicyUnit.java A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenGuestDistributionBalancePolicyUnit.java A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenGuestDistributionWeightPolicyUnit.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VDS.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java M backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd M backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/ClusterMapper.java A packaging/dbscripts/upgrade/03_04_0390_add_even_guest_distribution_policy.sql 9 files changed, 210 insertions(+), 11 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/03/23103/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/PolicyUnitImpl.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/PolicyUnitImpl.java index 517197b..7033881 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/PolicyUnitImpl.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/PolicyUnitImpl.java @@ -9,6 +9,8 @@ import org.ovirt.engine.core.bll.scheduling.policyunits.CpuLevelFilterPolicyUnit; import org.ovirt.engine.core.bll.scheduling.policyunits.EvenDistributionBalancePolicyUnit; import org.ovirt.engine.core.bll.scheduling.policyunits.EvenDistributionWeightPolicyUnit; +import org.ovirt.engine.core.bll.scheduling.policyunits.EvenGuestDistributionBalancePolicyUnit; +import org.ovirt.engine.core.bll.scheduling.policyunits.EvenGuestDistributionWeightPolicyUnit; import org.ovirt.engine.core.bll.scheduling.policyunits.HostedEngineHAClusterFilterPolicyUnit; import org.ovirt.engine.core.bll.scheduling.policyunits.HostedEngineHAClusterWeightPolicyUnit; import org.ovirt.engine.core.bll.scheduling.policyunits.MemoryPolicyUnit; @@ -75,6 +77,14 @@ return new EvenDistributionBalancePolicyUnit(policyUnit); } break; + case "OptimalForEvenGuestDistribution": + if (policyUnit.getPolicyUnitType() == PolicyUnitType.Weight) { + return new EvenGuestDistributionWeightPolicyUnit(policyUnit); + } + else if (policyUnit.getPolicyUnitType() == PolicyUnitType.LoadBalancing) { + return new EvenGuestDistributionBalancePolicyUnit(policyUnit); + } + break; default: break; } @@ -182,6 +192,17 @@ policyUnit.setEnabled(enabled); } + protected int tryParseWithDefault(String candidate, int defaultValue) { + if (candidate != null) { + try { + return Integer.parseInt(candidate); + } catch (Exception e) { + // do nothing + } + } + return defaultValue; + } + public final PolicyUnit getPolicyUnit() { return policyUnit; } 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..c9ee5b8 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 @@ -44,12 +44,21 @@ return null; } // get vds that over committed for the time defined + /* returns list of Hosts with + * cpuUtilization >= highUtilization + * && cpuOverCommitMinutes >= CpuOverCommitDurationMinutes + */ List<VDS> overUtilizedHosts = getOverUtilizedHosts(hosts, parameters); + // if no hosts is overutilized, then there is nothing to balance... if (overUtilizedHosts == null || overUtilizedHosts.size() == 0) { return null; } + + // returns hosts with utilization lower then the specified threshold List<VDS> underUtilizedHosts = getUnderUtilizedHosts(cluster, hosts, parameters); + + //if no host has a spare power, then there is nothing we can do to balance it.. if (underUtilizedHosts == null || underUtilizedHosts.size() == 0) { return null; } @@ -188,16 +197,5 @@ private static int calculateCpuUsage(VM o1) { return o1.getUsageCpuPercent() * o1.getNumOfCpus(); } - } - - protected int tryParseWithDefault(String candidate, int defaultValue) { - if (candidate != null) { - try { - return Integer.parseInt(candidate); - } catch (Exception e) { - // do nothing - } - } - return defaultValue; } } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenGuestDistributionBalancePolicyUnit.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenGuestDistributionBalancePolicyUnit.java new file mode 100644 index 0000000..9affcab --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenGuestDistributionBalancePolicyUnit.java @@ -0,0 +1,96 @@ +package org.ovirt.engine.core.bll.scheduling.policyunits; + +import org.ovirt.engine.core.common.businessentities.VDS; +import org.ovirt.engine.core.common.businessentities.VDSGroup; +import org.ovirt.engine.core.common.config.Config; +import org.ovirt.engine.core.common.config.ConfigValues; +import org.ovirt.engine.core.common.scheduling.PolicyUnit; +import org.ovirt.engine.core.utils.linq.LinqUtils; +import org.ovirt.engine.core.utils.linq.Predicate; + +import java.util.List; +import java.util.Map; + +public class EvenGuestDistributionBalancePolicyUnit extends EvenDistributionBalancePolicyUnit { + + + public EvenGuestDistributionBalancePolicyUnit (PolicyUnit policyUnit) { + super(policyUnit); + } + + private int getSPMGraceDefaultValue() { + return Config.<Integer> getValue(ConfigValues.SPMVMGraceForEvenGuestDistribute); + } + + private int getMigrationThresholdDefault() { + return Config.<Integer> getValue(ConfigValues.MigrationThresholdForEvenGuestDistribute); + } + + private int getHighVMCountDefaultValue() { + return Config.<Integer> getValue(ConfigValues.HighVMCountForEvenGuestDistribute); + } + + /* returns the number of running VMS on given VDS + if the VDS is SPM the return value is the number of running VMS + SPMVMCountGrace + */ + private int getOccupiedVMSLots(VDS vds, Map<String, String> parameters) { + int occupiedSlots = vds.getVmActive(); + final int SPMVMCountGrace = tryParseWithDefault(parameters.get("SPMVMCountGrace"), + getSPMGraceDefaultValue()); + if (vds.isSpm()) + occupiedSlots += SPMVMCountGrace; + + return occupiedSlots; + } + + private VDS getWorstVDS(List<VDS> relevantHosts, Map<String, String> parameters) { + VDS worstVDS = relevantHosts.get(0); + for (VDS vds: relevantHosts) { + if (getOccupiedVMSLots(vds, parameters) > getOccupiedVMSLots(worstVDS, parameters)) + worstVDS = vds; + } + + return worstVDS; + } + + @Override + protected List<VDS> getOverUtilizedHosts(List<VDS> relevantHosts, + final Map<String, String> parameters) { + + final int highVmCountUtilization = tryParseWithDefault(parameters.get("HighVMCount"), + getHighVMCountDefaultValue()); + + final VDS worstVDS = getWorstVDS(relevantHosts, parameters); + if (getOccupiedVMSLots(worstVDS, parameters) < highVmCountUtilization) { + log.debugFormat("No host is overutilized, the worst is {1} with {2} occupied VM slots", worstVDS.getName(), getOccupiedVMSLots(worstVDS, parameters)); + return null; + } + + return LinqUtils.filter(relevantHosts, new Predicate<VDS>() { + @Override + public boolean eval(VDS p) { + return getOccupiedVMSLots(p, parameters) >= getOccupiedVMSLots(worstVDS, parameters); + } + }); + } + + @Override + protected List<VDS> getUnderUtilizedHosts(VDSGroup cluster, + List<VDS> relevantHosts, + final Map<String, String> parameters) { + + final int migrationThreshold = tryParseWithDefault(parameters.get("MigrationThreshold"), + getMigrationThresholdDefault()); + + final VDS worstVDS = getWorstVDS(relevantHosts, parameters); + + return LinqUtils.filter(relevantHosts, new Predicate<VDS>() { + @Override + public boolean eval(VDS p) { + int distance = getOccupiedVMSLots(worstVDS, parameters) - getOccupiedVMSLots(p, parameters); + return distance < migrationThreshold; + } + }); + } + +} diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenGuestDistributionWeightPolicyUnit.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenGuestDistributionWeightPolicyUnit.java new file mode 100644 index 0000000..692c921 --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenGuestDistributionWeightPolicyUnit.java @@ -0,0 +1,50 @@ +package org.ovirt.engine.core.bll.scheduling.policyunits; + +import org.ovirt.engine.core.bll.scheduling.PolicyUnitImpl; +import org.ovirt.engine.core.common.businessentities.VDS; +import org.ovirt.engine.core.common.businessentities.VDSGroup; +import org.ovirt.engine.core.common.businessentities.VM; +import org.ovirt.engine.core.common.config.Config; +import org.ovirt.engine.core.common.config.ConfigValues; +import org.ovirt.engine.core.common.scheduling.PolicyUnit; +import org.ovirt.engine.core.common.utils.Pair; +import org.ovirt.engine.core.compat.Guid; +import org.ovirt.engine.core.dal.dbbroker.DbFacade; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class EvenGuestDistributionWeightPolicyUnit extends PolicyUnitImpl { + public EvenGuestDistributionWeightPolicyUnit (PolicyUnit policyUnit) { + super(policyUnit); + } + + private int getSPMGraceDefaultValue() { + return Config.<Integer> getValue(ConfigValues.SPMVMGraceForEvenGuestDistribute); + } + + private int getOccupiedVMSLots(VDS vds, Map<String, String> parameters) { + int occupiedSlots = vds.getVmActive(); + final int SPMVMCountGrace = tryParseWithDefault(parameters.get("SPMVMCountGrace"), + getSPMGraceDefaultValue()); + if (vds.isSpm()) + occupiedSlots += SPMVMCountGrace; + + return occupiedSlots; + } + + private int calcEvenGuestDistributionScore(VDS vds) { + return Math.max(0, vds.getVmCount()); + } + + @Override + public List<Pair<Guid, Integer>> score(List<VDS> hosts, VM vm, Map<String, String> parameters) { + VDSGroup vdsGroup = DbFacade.getInstance().getVdsGroupDao().get(hosts.get(0).getVdsGroupId()); + List<Pair<Guid, Integer>> scores = new ArrayList<Pair<Guid, Integer>>(); + for (VDS vds : hosts) { + scores.add(new Pair<Guid, Integer>(vds.getId(), calcEvenGuestDistributionScore(vds))); + } + return scores; + } +} diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VDS.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VDS.java index 6c64c74..1ad5de4 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VDS.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VDS.java @@ -1185,6 +1185,10 @@ _spm_status = value; } + public boolean isSpm() { + return _spm_status == VdsSpmStatus.SPM; + } + public NonOperationalReason getNonOperationalReason() { return this.mVdsDynamic.getNonOperationalReason(); } diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java index 6113ddd..b5eee3b 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java @@ -427,6 +427,18 @@ @DefaultValueAttribute("120") MaxVdsMemOverCommitForServers, @Reloadable + @TypeConverterAttribute(Integer.class) + @DefaultValueAttribute("10") + HighVMCountForEvenGuestDistribute, + @Reloadable + @TypeConverterAttribute(Integer.class) + @DefaultValueAttribute("5") + SPMVMGraceForEvenGuestDistribute, + @Reloadable + @TypeConverterAttribute(Integer.class) + @DefaultValueAttribute("5") + MigrationThresholdForEvenGuestDistribute, + @Reloadable @TypeConverterAttribute(Boolean.class) @DefaultValueAttribute("true") AutoInstallCertificateOnApprove, diff --git a/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd b/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd index 012dd94..eef4a4b 100644 --- a/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd +++ b/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd @@ -1240,6 +1240,14 @@ </xs:appinfo> </xs:annotation> </xs:attribute> + <xs:attribute name="vmscount" type="xs:int"> + <xs:annotation> + <xs:appinfo> + <jaxb:property generateIsSetMethod="false"/> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + </xs:complexType> <xs:complexType name="SchedulingPolicy"> diff --git a/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/ClusterMapper.java b/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/ClusterMapper.java index 7b25265..036915f 100644 --- a/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/ClusterMapper.java +++ b/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/ClusterMapper.java @@ -28,6 +28,7 @@ private static final String CPU_OVER_COMMIT_DURATION_MINUTES = "CpuOverCommitDurationMinutes"; private static final String HIGH_UTILIZATION = "HighUtilization"; private static final String LOW_UTILIZATION = "LowUtilization"; + private static final String HIGH_VM_COUNT = "HighVmCount"; static final org.ovirt.engine.core.compat.Version min_thp_version = new org.ovirt.engine.core.compat.Version(3, 0); @Mapping(from = Cluster.class, to = VDSGroup.class) @@ -188,6 +189,9 @@ if (thresholds.getHigh() != null) { entity.getClusterPolicyProperties().put(HIGH_UTILIZATION, thresholds.getHigh().toString()); } + if (thresholds.getHigh() != null) { + entity.getClusterPolicyProperties().put(HIGH_VM_COUNT, thresholds.getVmscount().toString()); + } if (thresholds.getDuration() != null) { int round = Math.round(thresholds.getDuration() / 60.0f); entity.getClusterPolicyProperties().put(CPU_OVER_COMMIT_DURATION_MINUTES, Integer.toString(round)); diff --git a/packaging/dbscripts/upgrade/03_04_0390_add_even_guest_distribution_policy.sql b/packaging/dbscripts/upgrade/03_04_0390_add_even_guest_distribution_policy.sql new file mode 100644 index 0000000..fb782e5 --- /dev/null +++ b/packaging/dbscripts/upgrade/03_04_0390_add_even_guest_distribution_policy.sql @@ -0,0 +1,6 @@ +INSERT INTO policy_units (id, name, is_internal, type, enabled, custom_properties_regex, description) VALUES ('d58c8e32-44e1-418f-9222-52cd887bf9e0', 'OptimalForEvenGuestDistribution', true, 2, true, +'{"HighVmCount" : "^([5-9][0-9])$"}', 'Even VM count distribution policy'); +INSERT INTO cluster_policies (id, name, description, is_locked, is_default, custom_properties) VALUES ('8d5d7bec-68de-4a67-b53e-0ac54686d579', 'VM_Evenly_Distributed', '', true, false, '{"HighVMCount" : "10"}'); + +-- add the policy units to the VM_Evenly_Distributed cluster policy +INSERT INTO cluster_policy_units (cluster_policy_id, policy_unit_id, filter_sequence, factor) VALUES ('8d5d7bec-68de-4a67-b53e-0ac54686d579', 'd58c8e32-44e1-418f-9222-52cd887bf9e0', 0, 1); -- To view, visit http://gerrit.ovirt.org/23103 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I2f2036dfc8a410c787a195d7d56ac3ed4ace81a7 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Jiří Moskovčák <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
