Skip to content

Commit 4f40eae

Browse files
authored
DRS: Use free metrics insteado of used for computation (apache#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.
1 parent b8d3e34 commit 4f40eae

4 files changed

Lines changed: 44 additions & 44 deletions

File tree

api/src/main/java/org/apache/cloudstack/cluster/ClusterDrsAlgorithm.java

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -65,18 +65,18 @@ public interface ClusterDrsAlgorithm extends Adapter {
6565
* the service offering for the virtual machine
6666
* @param destHost
6767
* the destination host for the virtual machine
68-
* @param hostCpuUsedMap
69-
* a map of host IDs to the amount of CPU used on each host
70-
* @param hostMemoryUsedMap
71-
* a map of host IDs to the amount of memory used on each host
68+
* @param hostCpuFreeMap
69+
* a map of host IDs to the amount of CPU free on each host
70+
* @param hostMemoryFreeMap
71+
* a map of host IDs to the amount of memory free on each host
7272
* @param requiresStorageMotion
7373
* whether storage motion is required for the virtual machine
7474
*
7575
* @return a ternary containing improvement, cost, benefit
7676
*/
7777
Ternary<Double, Double, Double> getMetrics(long clusterId, VirtualMachine vm, ServiceOffering serviceOffering,
78-
Host destHost, Map<Long, Long> hostCpuUsedMap,
79-
Map<Long, Long> hostMemoryUsedMap, Boolean requiresStorageMotion);
78+
Host destHost, Map<Long, Long> hostCpuFreeMap,
79+
Map<Long, Long> hostMemoryFreeMap, Boolean requiresStorageMotion);
8080

8181
/**
8282
* Calculates the imbalance of the cluster after a virtual machine migration.
@@ -87,30 +87,30 @@ Ternary<Double, Double, Double> getMetrics(long clusterId, VirtualMachine vm, Se
8787
* the virtual machine being migrated
8888
* @param destHost
8989
* the destination host for the virtual machine
90-
* @param hostCpuUsedMap
91-
* a map of host IDs to the amount of CPU used on each host
92-
* @param hostMemoryUsedMap
93-
* a map of host IDs to the amount of memory used on each host
90+
* @param hostCpuFreeMap
91+
* a map of host IDs to the amount of CPU free on each host
92+
* @param hostMemoryFreeMap
93+
* a map of host IDs to the amount of memory free on each host
9494
*
9595
* @return a pair containing the CPU and memory imbalance of the cluster after the migration
9696
*/
9797
default Pair<Double, Double> getImbalancePostMigration(ServiceOffering serviceOffering, VirtualMachine vm,
98-
Host destHost, Map<Long, Long> hostCpuUsedMap,
99-
Map<Long, Long> hostMemoryUsedMap) {
98+
Host destHost, Map<Long, Long> hostCpuFreeMap,
99+
Map<Long, Long> hostMemoryFreeMap) {
100100
List<Long> postCpuList = new ArrayList<>();
101101
List<Long> postMemoryList = new ArrayList<>();
102102
final int vmCpu = serviceOffering.getCpu() * serviceOffering.getSpeed();
103103
final long vmRam = serviceOffering.getRamSize() * 1024L * 1024L;
104104

105-
for (Long hostId : hostCpuUsedMap.keySet()) {
106-
long cpu = hostCpuUsedMap.get(hostId);
107-
long memory = hostMemoryUsedMap.get(hostId);
105+
for (Long hostId : hostCpuFreeMap.keySet()) {
106+
long cpu = hostCpuFreeMap.get(hostId);
107+
long memory = hostMemoryFreeMap.get(hostId);
108108
if (hostId == destHost.getId()) {
109-
postCpuList.add(cpu + vmCpu);
110-
postMemoryList.add(memory + vmRam);
111-
} else if (hostId.equals(vm.getHostId())) {
112109
postCpuList.add(cpu - vmCpu);
113110
postMemoryList.add(memory - vmRam);
111+
} else if (hostId.equals(vm.getHostId())) {
112+
postCpuList.add(cpu + vmCpu);
113+
postMemoryList.add(memory + vmRam);
114114
} else {
115115
postCpuList.add(cpu);
116116
postMemoryList.add(memory);

plugins/drs/cluster/balanced/src/test/java/org/apache/cloudstack/cluster/BalancedTest.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public class BalancedTest {
6868

6969
List<Long> cpuList, memoryList;
7070

71-
Map<Long, Long> hostCpuUsedMap, hostMemoryUsedMap;
71+
Map<Long, Long> hostCpuFreeMap, hostMemoryFreeMap;
7272

7373

7474
@Mock
@@ -105,13 +105,13 @@ public void setUp() throws NoSuchFieldException, IllegalAccessException {
105105
cpuList = Arrays.asList(1L, 2L);
106106
memoryList = Arrays.asList(512L, 2048L);
107107

108-
hostCpuUsedMap = new HashMap<>();
109-
hostCpuUsedMap.put(1L, 1000L);
110-
hostCpuUsedMap.put(2L, 2000L);
108+
hostCpuFreeMap = new HashMap<>();
109+
hostCpuFreeMap.put(1L, 2000L);
110+
hostCpuFreeMap.put(2L, 1000L);
111111

112-
hostMemoryUsedMap = new HashMap<>();
113-
hostMemoryUsedMap.put(1L, 512L * 1024L * 1024L);
114-
hostMemoryUsedMap.put(2L, 2048L * 1024L * 1024L);
112+
hostMemoryFreeMap = new HashMap<>();
113+
hostMemoryFreeMap.put(1L, 2048L * 1024L * 1024L);
114+
hostMemoryFreeMap.put(2L, 512L * 1024L * 1024L);
115115
}
116116

117117
private void overrideDefaultConfigValue(final ConfigKey configKey, final String name,
@@ -191,7 +191,7 @@ public void needsDrsWithUnknown() throws ConfigurationException, NoSuchFieldExce
191191
public void getMetricsWithCpu() throws NoSuchFieldException, IllegalAccessException {
192192
overrideDefaultConfigValue(ClusterDrsMetric, "_defaultValue", "cpu");
193193
Ternary<Double, Double, Double> result = balanced.getMetrics(clusterId, vm3, serviceOffering, destHost,
194-
hostCpuUsedMap, hostMemoryUsedMap, false);
194+
hostCpuFreeMap, hostMemoryFreeMap, false);
195195
assertEquals(0.0, result.first(), 0.01);
196196
assertEquals(0.0, result.second(), 0.0);
197197
assertEquals(1.0, result.third(), 0.0);
@@ -205,7 +205,7 @@ public void getMetricsWithCpu() throws NoSuchFieldException, IllegalAccessExcept
205205
public void getMetricsWithMemory() throws NoSuchFieldException, IllegalAccessException {
206206
overrideDefaultConfigValue(ClusterDrsMetric, "_defaultValue", "memory");
207207
Ternary<Double, Double, Double> result = balanced.getMetrics(clusterId, vm3, serviceOffering, destHost,
208-
hostCpuUsedMap, hostMemoryUsedMap, false);
208+
hostCpuFreeMap, hostMemoryFreeMap, false);
209209
assertEquals(0.4, result.first(), 0.01);
210210
assertEquals(0, result.second(), 0.0);
211211
assertEquals(1, result.third(), 0.0);
@@ -219,7 +219,7 @@ public void getMetricsWithMemory() throws NoSuchFieldException, IllegalAccessExc
219219
public void getMetricsWithDefault() throws NoSuchFieldException, IllegalAccessException {
220220
overrideDefaultConfigValue(ClusterDrsMetric, "_defaultValue", "both");
221221
Ternary<Double, Double, Double> result = balanced.getMetrics(clusterId, vm3, serviceOffering, destHost,
222-
hostCpuUsedMap, hostMemoryUsedMap, false);
222+
hostCpuFreeMap, hostMemoryFreeMap, false);
223223
assertEquals(0.4, result.first(), 0.01);
224224
assertEquals(0, result.second(), 0.0);
225225
assertEquals(1, result.third(), 0.0);

plugins/drs/cluster/condensed/src/test/java/org/apache/cloudstack/cluster/CondensedTest.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public class CondensedTest {
6666

6767
List<Long> cpuList, memoryList;
6868

69-
Map<Long, Long> hostCpuUsedMap, hostMemoryUsedMap;
69+
Map<Long, Long> hostCpuFreeMap, hostMemoryFreeMap;
7070

7171

7272
private AutoCloseable closeable;
@@ -98,13 +98,13 @@ public void setUp() throws NoSuchFieldException, IllegalAccessException {
9898
cpuList = Arrays.asList(1L, 2L);
9999
memoryList = Arrays.asList(512L, 2048L);
100100

101-
hostCpuUsedMap = new HashMap<>();
102-
hostCpuUsedMap.put(1L, 1000L);
103-
hostCpuUsedMap.put(2L, 2000L);
101+
hostCpuFreeMap = new HashMap<>();
102+
hostCpuFreeMap.put(1L, 2000L);
103+
hostCpuFreeMap.put(2L, 1000L);
104104

105-
hostMemoryUsedMap = new HashMap<>();
106-
hostMemoryUsedMap.put(1L, 512L * 1024L * 1024L);
107-
hostMemoryUsedMap.put(2L, 2048L * 1024L * 1024L);
105+
hostMemoryFreeMap = new HashMap<>();
106+
hostMemoryFreeMap.put(1L, 2048L * 1024L * 1024L);
107+
hostMemoryFreeMap.put(2L, 512L * 1024L * 1024L);
108108
}
109109

110110
private void overrideDefaultConfigValue(final ConfigKey configKey,
@@ -185,7 +185,7 @@ public void needsDrsWithUnknown() throws ConfigurationException, NoSuchFieldExce
185185
public void getMetricsWithCpu() throws NoSuchFieldException, IllegalAccessException {
186186
overrideDefaultConfigValue(ClusterDrsMetric, "_defaultValue", "cpu");
187187
Ternary<Double, Double, Double> result = condensed.getMetrics(clusterId, vm3, serviceOffering, destHost,
188-
hostCpuUsedMap, hostMemoryUsedMap, false);
188+
hostCpuFreeMap, hostMemoryFreeMap, false);
189189
assertEquals(0.0, result.first(), 0.0);
190190
assertEquals(0, result.second(), 0.0);
191191
assertEquals(1, result.third(), 0.0);
@@ -199,7 +199,7 @@ public void getMetricsWithCpu() throws NoSuchFieldException, IllegalAccessExcept
199199
public void getMetricsWithMemory() throws NoSuchFieldException, IllegalAccessException {
200200
overrideDefaultConfigValue(ClusterDrsMetric, "_defaultValue", "memory");
201201
Ternary<Double, Double, Double> result = condensed.getMetrics(clusterId, vm3, serviceOffering, destHost,
202-
hostCpuUsedMap, hostMemoryUsedMap, false);
202+
hostCpuFreeMap, hostMemoryFreeMap, false);
203203
assertEquals(-0.4, result.first(), 0.01);
204204
assertEquals(0, result.second(), 0.0);
205205
assertEquals(1, result.third(), 0.0);
@@ -213,7 +213,7 @@ public void getMetricsWithMemory() throws NoSuchFieldException, IllegalAccessExc
213213
public void getMetricsWithDefault() throws NoSuchFieldException, IllegalAccessException {
214214
overrideDefaultConfigValue(ClusterDrsMetric, "_defaultValue", "both");
215215
Ternary<Double, Double, Double> result = condensed.getMetrics(clusterId, vm3, serviceOffering, destHost,
216-
hostCpuUsedMap, hostMemoryUsedMap, false);
216+
hostCpuFreeMap, hostMemoryFreeMap, false);
217217
assertEquals(-0.4, result.first(), 0.0001);
218218
assertEquals(0, result.second(), 0.0);
219219
assertEquals(1, result.third(), 0.0);

server/src/main/java/org/apache/cloudstack/cluster/ClusterDrsServiceImpl.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -354,9 +354,9 @@ List<Ternary<VirtualMachine, Host, Host>> getDrsPlan(Cluster cluster,
354354
hostList.stream().map(HostVO::getId).toArray(Long[]::new));
355355

356356
Map<Long, Long> hostCpuMap = hostJoinList.stream().collect(Collectors.toMap(HostJoinVO::getId,
357-
hostJoin -> hostJoin.getCpuUsedCapacity() + hostJoin.getCpuReservedCapacity()));
357+
hostJoin -> hostJoin.getCpus() * hostJoin.getSpeed() - hostJoin.getCpuReservedCapacity() - hostJoin.getCpuUsedCapacity()));
358358
Map<Long, Long> hostMemoryMap = hostJoinList.stream().collect(Collectors.toMap(HostJoinVO::getId,
359-
hostJoin -> hostJoin.getMemUsedCapacity() + hostJoin.getMemReservedCapacity()));
359+
hostJoin -> hostJoin.getTotalMemory() - hostJoin.getMemUsedCapacity() - hostJoin.getMemReservedCapacity()));
360360

361361
Map<Long, ServiceOffering> vmIdServiceOfferingMap = new HashMap<>();
362362

@@ -387,10 +387,10 @@ List<Ternary<VirtualMachine, Host, Host>> getDrsPlan(Cluster cluster,
387387
long vmCpu = (long) serviceOffering.getCpu() * serviceOffering.getSpeed();
388388
long vmMemory = serviceOffering.getRamSize() * 1024L * 1024L;
389389

390-
hostCpuMap.put(vm.getHostId(), hostCpuMap.get(vm.getHostId()) - vmCpu);
391-
hostCpuMap.put(destHost.getId(), hostCpuMap.get(destHost.getId()) + vmCpu);
392-
hostMemoryMap.put(vm.getHostId(), hostMemoryMap.get(vm.getHostId()) - vmMemory);
393-
hostMemoryMap.put(destHost.getId(), hostMemoryMap.get(destHost.getId()) + vmMemory);
390+
hostCpuMap.put(vm.getHostId(), hostCpuMap.get(vm.getHostId()) + vmCpu);
391+
hostCpuMap.put(destHost.getId(), hostCpuMap.get(destHost.getId()) - vmCpu);
392+
hostMemoryMap.put(vm.getHostId(), hostMemoryMap.get(vm.getHostId()) + vmMemory);
393+
hostMemoryMap.put(destHost.getId(), hostMemoryMap.get(destHost.getId()) - vmMemory);
394394
vm.setHostId(destHost.getId());
395395
iteration++;
396396
}

0 commit comments

Comments
 (0)