devmadhuu commented on code in PR #11322:
URL: https://github.com/apache/ozone/pull/11322#discussion_r4209985931


##########
hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/diskbalancer/policy/DefaultContainerChoosingPolicy.java:
##########
@@ -91,62 +99,123 @@ public ContainerCandidate 
chooseVolumesAndContainer(OzoneContainer ozoneContaine
         return null;
       }
 
-      // Calculate ideal usage and threshold range (once)
-      final double idealUsage = getIdealUsage(volumeUsages);
-      final double actualThreshold = thresholdPercentage / 100.0;
-      final double lowerThreshold = idealUsage - actualThreshold;
-      final double upperThreshold = idealUsage + actualThreshold;
-
-      if (LOG.isDebugEnabled()) {
-        logVolumeBalancingState(volumeUsages, idealUsage, thresholdPercentage,
-            lowerThreshold, upperThreshold, deltaMap);
+      // Balance each storage type independently so a container never crosses 
types. Try the type
+      // with the largest threshold violation first. StorageType order is only 
a deterministic
+      // tie-breaker.
+      final Map<StorageType, List<VolumeFixedUsage>> usagesByStorageType =
+          getUsableVolumesByStorageType(volumeUsages);
+      final List<Map.Entry<StorageType, List<VolumeFixedUsage>>> 
storageTypeGroups =
+          usagesByStorageType.entrySet().stream()
+              .filter(entry -> hasMultipleUsableVolumes(entry.getKey(), 
entry.getValue()))
+              .sorted(Comparator
+                  .<Map.Entry<StorageType, 
List<VolumeFixedUsage>>>comparingDouble(
+                      entry -> getThresholdViolation(entry.getValue(), 
thresholdPercentage))
+                  .reversed()
+                  .thenComparingInt(entry -> entry.getKey().ordinal()))
+              .collect(Collectors.toList());
+      for (Map.Entry<StorageType, List<VolumeFixedUsage>> entry : 
storageTypeGroups) {
+        final StorageType storageType = entry.getKey();
+        final List<VolumeFixedUsage> sameTypeUsages = entry.getValue();
+        final ContainerCandidate candidate = 
chooseWithinStorageType(ozoneContainer, sameTypeUsages,
+            deltaMap, inProgressContainerIDs, thresholdPercentage, 
movableContainerStates, storageType);
+        if (candidate != null) {
+          return candidate;
+        }
       }
+      LOG.debug("Failed to find appropriate destination volume and container 
in any storage type.");
+      return null;
+    } finally {
+      lock.unlock();
+    }
+  }
 
-      // Get highest and lowest utilization volumes
-      final VolumeFixedUsage highestUsage = 
volumeUsages.get(volumeUsages.size() - 1);
-      final VolumeFixedUsage lowestUsage = volumeUsages.get(0);
+  private static boolean hasMultipleUsableVolumes(StorageType storageType,
+      List<VolumeFixedUsage> volumeUsages) {
+    if (volumeUsages.size() >= 2) {
+      return true;
+    }
+    LOG.debug("Skipping storage type {} for disk balancing: only {} usable 
volume(s)",
+        storageType, volumeUsages.size());
+    return false;
+  }
 
-      // Only return null if highest is below upper threshold AND lowest is 
above lower threshold
-      if (highestUsage.getUtilization() < upperThreshold &&
-          lowestUsage.getUtilization() > lowerThreshold) {
-        return null;
-      }
+  private static double getThresholdViolation(List<VolumeFixedUsage> 
volumeUsages,

Review Comment:
   Done.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to