ashishkumar50 commented on code in PR #11342:
URL: https://github.com/apache/ozone/pull/11342#discussion_r4245112347


##########
hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/container/balancer/ContainerBalancerAdvisor.java:
##########
@@ -82,6 +88,187 @@ public static List<ContainerBalancerEstimation> 
estimate(OzoneConfiguration conf
     return Collections.unmodifiableList(estimations);
   }
 
+  /**
+   * Recommends balancer configuration for one or more balancer profiles.
+   *
+   * <p>If {@link AdvisorRequest#profile} is set, returns a result for that 
profile only.
+   * Otherwise returns SLOW, MEDIUM, and FAST. Per-profile validation failures 
are returned with
+   * {@link ContainerBalancerRecommendation#succeeded()} false instead of 
aborting other profiles.
+   */
+  public static List<ContainerBalancerRecommendation> recommend(
+      OzoneConfiguration conf, AdvisorRequest request) {
+    Objects.requireNonNull(conf, "conf");
+    Objects.requireNonNull(request, "request");
+    List<DatanodeUsageInfoProto> nodes = Objects.requireNonNull(request.nodes, 
"nodes");
+
+    ContainerBalancerConfiguration balancerConfig = 
conf.getObject(ContainerBalancerConfiguration.class);
+
+    double thresholdPercent = request.thresholdPercent != null
+        ? request.thresholdPercent
+        : balancerConfig.getThreshold();
+    validateThresholdPercent(thresholdPercent);
+    double thresholdRatio = thresholdPercent / 100.0;
+    Set<String> includeNodes = request.includeNodes != null
+        ? request.includeNodes
+        : balancerConfig.getIncludeNodes();
+    Set<String> excludeNodes = request.excludeNodes != null
+        ? request.excludeNodes
+        : balancerConfig.getExcludeNodes();
+
+    ContainerBalancerClusterSnapshot snapshot = 
ContainerBalancerClusterAnalyzer.analyze(
+        nodes, thresholdRatio, includeNodes, excludeNodes);
+
+    List<ContainerBalancerProfile> profiles = 
selectProfilesForRecommend(request);
+    if (isClusterAlreadyBalanced(snapshot)) {
+      return recommendationsForBalancedCluster(profiles, thresholdPercent);
+    }
+    validateSnapshotForEstimation(snapshot);
+    List<ContainerBalancerRecommendation> recommendations = new 
ArrayList<>(profiles.size());
+    for (ContainerBalancerProfile profile : profiles) {
+      recommendations.add(recommendForProfile(
+          conf, request, profile, snapshot, balancerConfig, thresholdPercent));
+    }
+    return Collections.unmodifiableList(recommendations);
+  }
+
+  private static boolean 
isClusterAlreadyBalanced(ContainerBalancerClusterSnapshot snapshot) {
+    return snapshot.getBytesToMove() <= 0
+        || (snapshot.getSourceCount() < 1 && snapshot.getTargetCount() < 1);
+  }
+
+  private static List<ContainerBalancerRecommendation> 
recommendationsForBalancedCluster(
+      List<ContainerBalancerProfile> profiles, double thresholdPercent) {
+    List<ContainerBalancerRecommendation> recommendations = new 
ArrayList<>(profiles.size());
+    for (ContainerBalancerProfile profile : profiles) {
+      recommendations.add(ContainerBalancerRecommendation.newBuilder()
+          .setProfile(profile)
+          .setThresholdPercent(thresholdPercent)
+          .setClusterBalanced(true)
+          .build());
+    }
+    return Collections.unmodifiableList(recommendations);
+  }
+
+  private static ContainerBalancerRecommendation recommendForProfile(
+      OzoneConfiguration conf,
+      AdvisorRequest request,
+      ContainerBalancerProfile profile,
+      ContainerBalancerClusterSnapshot snapshot,
+      ContainerBalancerConfiguration balancerConfig,
+      double thresholdPercent) {
+
+    ContainerBalancerRecommendation.Builder builder = 
ContainerBalancerRecommendation.newBuilder()
+        .setProfile(profile)
+        .setThresholdPercent(thresholdPercent);
+
+    try {
+      long moveReplicationTimeoutMillis = 
balancerConfig.getMoveReplicationTimeout().toMillis();
+      long moveTimeoutMillis = balancerConfig.getMoveTimeout().toMillis();
+      long balancingIntervalMillis = 
balancerConfig.getBalancingInterval().toMillis();
+      validateMoveTimeouts(conf, moveReplicationTimeoutMillis, 
moveTimeoutMillis);
+      validateBalancingIntervalMillis(balancingIntervalMillis);
+
+      ContainerBalancerEstimation estimation = estimateForProfile(
+          conf, request, profile, snapshot, balancerConfig, thresholdPercent);

Review Comment:
   The estimation is computed before `recommendedMaxMove` is derived, so it can 
use a different `max-size-to-move-per-iteration` value from the one printed in 
the recommended configuration and suggested command.
   
   Could we resolve the effective movement limits first and then run the 
estimation using those limits? Otherwise, the reported iteration count and 
duration may not reflect the configuration users are advised to apply.



-- 
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