DRS: Use free metrics insteado of used for computation (#8458)

This PR makes changes to use cluster's free metrics instead of used while computing imbalance for the cluster. This allows DRS to run for clusters where hosts doesn't have the same amount of metrics.
This commit is contained in:
Vishesh 2024-01-10 17:52:46 +05:30 committed by GitHub
parent b8d3e342be
commit 4f40eae1c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 44 deletions

View File

@ -65,18 +65,18 @@ public interface ClusterDrsAlgorithm extends Adapter {
* the service offering for the virtual machine
* @param destHost
* the destination host for the virtual machine
* @param hostCpuUsedMap
* a map of host IDs to the amount of CPU used on each host
* @param hostMemoryUsedMap
* a map of host IDs to the amount of memory used on each host
* @param hostCpuFreeMap
* a map of host IDs to the amount of CPU free on each host
* @param hostMemoryFreeMap
* a map of host IDs to the amount of memory free on each host
* @param requiresStorageMotion
* whether storage motion is required for the virtual machine
*
* @return a ternary containing improvement, cost, benefit
*/
Ternary<Double, Double, Double> getMetrics(long clusterId, VirtualMachine vm, ServiceOffering serviceOffering,
Host destHost, Map<Long, Long> hostCpuUsedMap,
Map<Long, Long> hostMemoryUsedMap, Boolean requiresStorageMotion);
Host destHost, Map<Long, Long> hostCpuFreeMap,
Map<Long, Long> hostMemoryFreeMap, Boolean requiresStorageMotion);
/**
* Calculates the imbalance of the cluster after a virtual machine migration.
@ -87,30 +87,30 @@ public interface ClusterDrsAlgorithm extends Adapter {
* the virtual machine being migrated
* @param destHost
* the destination host for the virtual machine
* @param hostCpuUsedMap
* a map of host IDs to the amount of CPU used on each host
* @param hostMemoryUsedMap
* a map of host IDs to the amount of memory used on each host
* @param hostCpuFreeMap
* a map of host IDs to the amount of CPU free on each host
* @param hostMemoryFreeMap
* a map of host IDs to the amount of memory free on each host
*
* @return a pair containing the CPU and memory imbalance of the cluster after the migration
*/
default Pair<Double, Double> getImbalancePostMigration(ServiceOffering serviceOffering, VirtualMachine vm,
Host destHost, Map<Long, Long> hostCpuUsedMap,
Map<Long, Long> hostMemoryUsedMap) {
Host destHost, Map<Long, Long> hostCpuFreeMap,
Map<Long, Long> hostMemoryFreeMap) {
List<Long> postCpuList = new ArrayList<>();
List<Long> postMemoryList = new ArrayList<>();
final int vmCpu = serviceOffering.getCpu() * serviceOffering.getSpeed();
final long vmRam = serviceOffering.getRamSize() * 1024L * 1024L;
for (Long hostId : hostCpuUsedMap.keySet()) {
long cpu = hostCpuUsedMap.get(hostId);
long memory = hostMemoryUsedMap.get(hostId);
for (Long hostId : hostCpuFreeMap.keySet()) {
long cpu = hostCpuFreeMap.get(hostId);
long memory = hostMemoryFreeMap.get(hostId);
if (hostId == destHost.getId()) {
postCpuList.add(cpu + vmCpu);
postMemoryList.add(memory + vmRam);
} else if (hostId.equals(vm.getHostId())) {
postCpuList.add(cpu - vmCpu);
postMemoryList.add(memory - vmRam);
} else if (hostId.equals(vm.getHostId())) {
postCpuList.add(cpu + vmCpu);
postMemoryList.add(memory + vmRam);
} else {
postCpuList.add(cpu);
postMemoryList.add(memory);

View File

@ -68,7 +68,7 @@ public class BalancedTest {
List<Long> cpuList, memoryList;
Map<Long, Long> hostCpuUsedMap, hostMemoryUsedMap;
Map<Long, Long> hostCpuFreeMap, hostMemoryFreeMap;
@Mock
@ -105,13 +105,13 @@ public class BalancedTest {
cpuList = Arrays.asList(1L, 2L);
memoryList = Arrays.asList(512L, 2048L);
hostCpuUsedMap = new HashMap<>();
hostCpuUsedMap.put(1L, 1000L);
hostCpuUsedMap.put(2L, 2000L);
hostCpuFreeMap = new HashMap<>();
hostCpuFreeMap.put(1L, 2000L);
hostCpuFreeMap.put(2L, 1000L);
hostMemoryUsedMap = new HashMap<>();
hostMemoryUsedMap.put(1L, 512L * 1024L * 1024L);
hostMemoryUsedMap.put(2L, 2048L * 1024L * 1024L);
hostMemoryFreeMap = new HashMap<>();
hostMemoryFreeMap.put(1L, 2048L * 1024L * 1024L);
hostMemoryFreeMap.put(2L, 512L * 1024L * 1024L);
}
private void overrideDefaultConfigValue(final ConfigKey configKey, final String name,
@ -191,7 +191,7 @@ public class BalancedTest {
public void getMetricsWithCpu() throws NoSuchFieldException, IllegalAccessException {
overrideDefaultConfigValue(ClusterDrsMetric, "_defaultValue", "cpu");
Ternary<Double, Double, Double> result = balanced.getMetrics(clusterId, vm3, serviceOffering, destHost,
hostCpuUsedMap, hostMemoryUsedMap, false);
hostCpuFreeMap, hostMemoryFreeMap, false);
assertEquals(0.0, result.first(), 0.01);
assertEquals(0.0, result.second(), 0.0);
assertEquals(1.0, result.third(), 0.0);
@ -205,7 +205,7 @@ public class BalancedTest {
public void getMetricsWithMemory() throws NoSuchFieldException, IllegalAccessException {
overrideDefaultConfigValue(ClusterDrsMetric, "_defaultValue", "memory");
Ternary<Double, Double, Double> result = balanced.getMetrics(clusterId, vm3, serviceOffering, destHost,
hostCpuUsedMap, hostMemoryUsedMap, false);
hostCpuFreeMap, hostMemoryFreeMap, false);
assertEquals(0.4, result.first(), 0.01);
assertEquals(0, result.second(), 0.0);
assertEquals(1, result.third(), 0.0);
@ -219,7 +219,7 @@ public class BalancedTest {
public void getMetricsWithDefault() throws NoSuchFieldException, IllegalAccessException {
overrideDefaultConfigValue(ClusterDrsMetric, "_defaultValue", "both");
Ternary<Double, Double, Double> result = balanced.getMetrics(clusterId, vm3, serviceOffering, destHost,
hostCpuUsedMap, hostMemoryUsedMap, false);
hostCpuFreeMap, hostMemoryFreeMap, false);
assertEquals(0.4, result.first(), 0.01);
assertEquals(0, result.second(), 0.0);
assertEquals(1, result.third(), 0.0);

View File

@ -66,7 +66,7 @@ public class CondensedTest {
List<Long> cpuList, memoryList;
Map<Long, Long> hostCpuUsedMap, hostMemoryUsedMap;
Map<Long, Long> hostCpuFreeMap, hostMemoryFreeMap;
private AutoCloseable closeable;
@ -98,13 +98,13 @@ public class CondensedTest {
cpuList = Arrays.asList(1L, 2L);
memoryList = Arrays.asList(512L, 2048L);
hostCpuUsedMap = new HashMap<>();
hostCpuUsedMap.put(1L, 1000L);
hostCpuUsedMap.put(2L, 2000L);
hostCpuFreeMap = new HashMap<>();
hostCpuFreeMap.put(1L, 2000L);
hostCpuFreeMap.put(2L, 1000L);
hostMemoryUsedMap = new HashMap<>();
hostMemoryUsedMap.put(1L, 512L * 1024L * 1024L);
hostMemoryUsedMap.put(2L, 2048L * 1024L * 1024L);
hostMemoryFreeMap = new HashMap<>();
hostMemoryFreeMap.put(1L, 2048L * 1024L * 1024L);
hostMemoryFreeMap.put(2L, 512L * 1024L * 1024L);
}
private void overrideDefaultConfigValue(final ConfigKey configKey,
@ -185,7 +185,7 @@ public class CondensedTest {
public void getMetricsWithCpu() throws NoSuchFieldException, IllegalAccessException {
overrideDefaultConfigValue(ClusterDrsMetric, "_defaultValue", "cpu");
Ternary<Double, Double, Double> result = condensed.getMetrics(clusterId, vm3, serviceOffering, destHost,
hostCpuUsedMap, hostMemoryUsedMap, false);
hostCpuFreeMap, hostMemoryFreeMap, false);
assertEquals(0.0, result.first(), 0.0);
assertEquals(0, result.second(), 0.0);
assertEquals(1, result.third(), 0.0);
@ -199,7 +199,7 @@ public class CondensedTest {
public void getMetricsWithMemory() throws NoSuchFieldException, IllegalAccessException {
overrideDefaultConfigValue(ClusterDrsMetric, "_defaultValue", "memory");
Ternary<Double, Double, Double> result = condensed.getMetrics(clusterId, vm3, serviceOffering, destHost,
hostCpuUsedMap, hostMemoryUsedMap, false);
hostCpuFreeMap, hostMemoryFreeMap, false);
assertEquals(-0.4, result.first(), 0.01);
assertEquals(0, result.second(), 0.0);
assertEquals(1, result.third(), 0.0);
@ -213,7 +213,7 @@ public class CondensedTest {
public void getMetricsWithDefault() throws NoSuchFieldException, IllegalAccessException {
overrideDefaultConfigValue(ClusterDrsMetric, "_defaultValue", "both");
Ternary<Double, Double, Double> result = condensed.getMetrics(clusterId, vm3, serviceOffering, destHost,
hostCpuUsedMap, hostMemoryUsedMap, false);
hostCpuFreeMap, hostMemoryFreeMap, false);
assertEquals(-0.4, result.first(), 0.0001);
assertEquals(0, result.second(), 0.0);
assertEquals(1, result.third(), 0.0);

View File

@ -354,9 +354,9 @@ public class ClusterDrsServiceImpl extends ManagerBase implements ClusterDrsServ
hostList.stream().map(HostVO::getId).toArray(Long[]::new));
Map<Long, Long> hostCpuMap = hostJoinList.stream().collect(Collectors.toMap(HostJoinVO::getId,
hostJoin -> hostJoin.getCpuUsedCapacity() + hostJoin.getCpuReservedCapacity()));
hostJoin -> hostJoin.getCpus() * hostJoin.getSpeed() - hostJoin.getCpuReservedCapacity() - hostJoin.getCpuUsedCapacity()));
Map<Long, Long> hostMemoryMap = hostJoinList.stream().collect(Collectors.toMap(HostJoinVO::getId,
hostJoin -> hostJoin.getMemUsedCapacity() + hostJoin.getMemReservedCapacity()));
hostJoin -> hostJoin.getTotalMemory() - hostJoin.getMemUsedCapacity() - hostJoin.getMemReservedCapacity()));
Map<Long, ServiceOffering> vmIdServiceOfferingMap = new HashMap<>();
@ -387,10 +387,10 @@ public class ClusterDrsServiceImpl extends ManagerBase implements ClusterDrsServ
long vmCpu = (long) serviceOffering.getCpu() * serviceOffering.getSpeed();
long vmMemory = serviceOffering.getRamSize() * 1024L * 1024L;
hostCpuMap.put(vm.getHostId(), hostCpuMap.get(vm.getHostId()) - vmCpu);
hostCpuMap.put(destHost.getId(), hostCpuMap.get(destHost.getId()) + vmCpu);
hostMemoryMap.put(vm.getHostId(), hostMemoryMap.get(vm.getHostId()) - vmMemory);
hostMemoryMap.put(destHost.getId(), hostMemoryMap.get(destHost.getId()) + vmMemory);
hostCpuMap.put(vm.getHostId(), hostCpuMap.get(vm.getHostId()) + vmCpu);
hostCpuMap.put(destHost.getId(), hostCpuMap.get(destHost.getId()) - vmCpu);
hostMemoryMap.put(vm.getHostId(), hostMemoryMap.get(vm.getHostId()) + vmMemory);
hostMemoryMap.put(destHost.getId(), hostMemoryMap.get(destHost.getId()) - vmMemory);
vm.setHostId(destHost.getId());
iteration++;
}