From 731ffbd38f900946b30486938ed04c27b46d08f5 Mon Sep 17 00:00:00 2001 From: sravani-revuri Date: Wed, 29 Jul 2026 11:01:55 +0530 Subject: [PATCH] HDDS-15657. excludeContainersDueToFailure resets every iteration, repeatedly failing containers keep being retried --- .../ContainerBalancerSelectionCriteria.java | 16 +++++++- .../balancer/ContainerBalancerTask.java | 3 +- .../balancer/TestContainerBalancerTask.java | 37 ++++++++++++++++++- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/balancer/ContainerBalancerSelectionCriteria.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/balancer/ContainerBalancerSelectionCriteria.java index c72cf5f03467..9df83a940441 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/balancer/ContainerBalancerSelectionCriteria.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/balancer/ContainerBalancerSelectionCriteria.java @@ -55,7 +55,7 @@ public class ContainerBalancerSelectionCriteria { private Map containerToSourceMap; private Set excludeContainers; private Set includeContainers; - private Set excludeContainersDueToFailure; + private final Set excludeContainersDueToFailure; private FindSourceStrategy findSourceStrategy; private Map> setMap; @@ -66,12 +66,24 @@ public ContainerBalancerSelectionCriteria( ContainerManager containerManager, FindSourceStrategy findSourceStrategy, Map containerToSourceMap) { + this(balancerConfiguration, nodeManager, replicationManager, containerManager, + findSourceStrategy, containerToSourceMap, new HashSet<>()); + } + + public ContainerBalancerSelectionCriteria( + ContainerBalancerConfiguration balancerConfiguration, + NodeManager nodeManager, + ReplicationManager replicationManager, + ContainerManager containerManager, + FindSourceStrategy findSourceStrategy, + Map containerToSourceMap, + Set excludeContainersDueToFailure) { this.balancerConfiguration = balancerConfiguration; this.nodeManager = nodeManager; this.replicationManager = replicationManager; this.containerManager = containerManager; this.containerToSourceMap = containerToSourceMap; - excludeContainersDueToFailure = new HashSet<>(); + this.excludeContainersDueToFailure = excludeContainersDueToFailure; excludeContainers = balancerConfiguration.getExcludeContainers(); includeContainers = balancerConfiguration.getIncludeContainers(); this.findSourceStrategy = findSourceStrategy; diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/balancer/ContainerBalancerTask.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/balancer/ContainerBalancerTask.java index 38554253bab3..331ccc3b8563 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/balancer/ContainerBalancerTask.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/balancer/ContainerBalancerTask.java @@ -108,6 +108,7 @@ public class ContainerBalancerTask implements Runnable { private Set selectedTargets; private Set selectedSources; + private final Set excludeContainersDueToFailure = new HashSet<>(); private FindTargetStrategy findTargetStrategy; private FindSourceStrategy findSourceStrategy; private Map> @@ -635,7 +636,7 @@ private boolean initializeIteration() { selectionCriteria = new ContainerBalancerSelectionCriteria(config, nodeManager, replicationManager, containerManager, findSourceStrategy, - containerToSourceMap); + containerToSourceMap, excludeContainersDueToFailure); return true; } diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/balancer/TestContainerBalancerTask.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/balancer/TestContainerBalancerTask.java index bb407c9b9a80..b74a58ebb554 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/balancer/TestContainerBalancerTask.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/balancer/TestContainerBalancerTask.java @@ -489,7 +489,42 @@ public void testConcurrentMoveCallbacksAccumulateMovedBytesAtomically() throws E moveCompletionExecutor.shutdownNow(); } } - + + @Test + public void testExcludeContainersDueToFailurePersistsAcrossIterations() throws Exception { + when(moveManager.move(any(ContainerID.class), any(DatanodeDetails.class), + any(DatanodeDetails.class))) + .thenReturn(CompletableFuture.completedFuture( + MoveManager.MoveResult.REPLICATION_NOT_HEALTHY_AFTER_MOVE)) + .thenReturn(CompletableFuture.completedFuture(MoveManager.MoveResult.COMPLETED)); + + balancerConfiguration.setThreshold(10); + balancerConfiguration.setIterations(2); + balancerConfiguration.setBalancingInterval(0); + balancerConfiguration.setMaxSizeEnteringTarget(10 * STORAGE_UNIT); + balancerConfiguration.setMaxSizeToMovePerIteration(100 * STORAGE_UNIT); + balancerConfiguration.setMaxDatanodesPercentageToInvolvePerIteration(100); + String includeNodes = nodesInCluster.get(0).getDatanodeDetails().getHostName() + "," + + nodesInCluster.get(nodesInCluster.size() - 1).getDatanodeDetails().getHostName(); + balancerConfiguration.setIncludeNodes(includeNodes); + + startBalancer(balancerConfiguration); + + ArgumentCaptor containerCaptor = ArgumentCaptor.forClass(ContainerID.class); + verify(moveManager, atLeast(1)).move(containerCaptor.capture(), + any(DatanodeDetails.class), any(DatanodeDetails.class)); + ContainerID failedContainerId = containerCaptor.getAllValues().get(0); + + assertTrue(containerBalancerTask.getSelectionCriteria() + .getExcludeDueToFailContainers().contains(failedContainerId)); + + long failedContainerMoveAttempts = containerCaptor.getAllValues().stream() + .filter(id -> id.equals(failedContainerId)) + .count(); + assertEquals(1, failedContainerMoveAttempts, + "Permanently failed container should not be retried in later iterations"); + } + /** * Generates a range of equally spaced utilization(that is, used / capacity) * values from 0 to 1.