From 63b257a5cef600c2cdee2b1669339fd0717e8fb2 Mon Sep 17 00:00:00 2001 From: Symious Date: Fri, 19 Jan 2024 16:08:59 +0800 Subject: [PATCH 01/11] HDDS-10160. Cache sort results in ContainerBalancerSelectionCriteria --- .../ContainerBalancerSelectionCriteria.java | 28 ++++++++++++++++--- 1 file changed, 24 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 8171320a54f8..b44fa426e818 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 @@ -32,7 +32,9 @@ import org.slf4j.LoggerFactory; import java.util.Comparator; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.NavigableSet; import java.util.Set; import java.util.TreeSet; @@ -52,6 +54,7 @@ public class ContainerBalancerSelectionCriteria { private Set selectedContainers; private Set excludeContainers; private FindSourceStrategy findSourceStrategy; + private Map> setMap; public ContainerBalancerSelectionCriteria( ContainerBalancerConfiguration balancerConfiguration, @@ -66,6 +69,7 @@ public ContainerBalancerSelectionCriteria( selectedContainers = new HashSet<>(); excludeContainers = balancerConfiguration.getExcludeContainers(); this.findSourceStrategy = findSourceStrategy; + this.setMap = new HashMap<>(); } /** @@ -92,15 +96,31 @@ private boolean isContainerReplicatingOrDeleting(ContainerID containerID) { */ public NavigableSet getCandidateContainers( DatanodeDetails node, long sizeMovedAlready) { - NavigableSet containerIDSet = - new TreeSet<>(orderContainersByUsedBytes().reversed()); + // Initialize containerSet for node + if (!setMap.containsKey(node)) { + NavigableSet newSet = + new TreeSet<>(orderContainersByUsedBytes().reversed()); + try { + newSet.addAll(nodeManager.getContainers(node)); + } catch (NodeNotFoundException e) { + LOG.warn("Could not find Datanode {} while selecting candidate " + + "containers for Container Balancer.", node.toString(), e); + return newSet; + } + setMap.put(node, newSet); + } + + // In case the node is removed try { - containerIDSet.addAll(nodeManager.getContainers(node)); + nodeManager.getContainers(node); } catch (NodeNotFoundException e) { LOG.warn("Could not find Datanode {} while selecting candidate " + "containers for Container Balancer.", node.toString(), e); - return containerIDSet; + setMap.remove(node); + return new TreeSet<>(); } + + NavigableSet containerIDSet = setMap.get(node); if (excludeContainers != null) { containerIDSet.removeAll(excludeContainers); } From e18496afbbf74a9674fd415f1e6ef3d8dbd1aee3 Mon Sep 17 00:00:00 2001 From: Symious Date: Mon, 22 Jan 2024 16:55:25 +0800 Subject: [PATCH 02/11] HDDS-10160. Sort out the code --- .../ContainerBalancerSelectionCriteria.java | 35 +++++++++---------- .../balancer/ContainerBalancerTask.java | 3 +- 2 files changed, 18 insertions(+), 20 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 b44fa426e818..2d1ae594b0f8 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 @@ -31,6 +31,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; @@ -92,32 +93,22 @@ private boolean isContainerReplicatingOrDeleting(ContainerID containerID) { * 5. Container should be closed. * 6. If the {@link LegacyReplicationManager} is enabled, then the container should not be an EC container. * @param node DatanodeDetails for which to find candidate containers. - * @return NavigableSet of candidate containers that satisfy the criteria. + * @return Set of candidate containers that satisfy the criteria. */ - public NavigableSet getCandidateContainers( + public Set getCandidateContainers( DatanodeDetails node, long sizeMovedAlready) { - // Initialize containerSet for node - if (!setMap.containsKey(node)) { - NavigableSet newSet = - new TreeSet<>(orderContainersByUsedBytes().reversed()); - try { - newSet.addAll(nodeManager.getContainers(node)); - } catch (NodeNotFoundException e) { - LOG.warn("Could not find Datanode {} while selecting candidate " + - "containers for Container Balancer.", node.toString(), e); - return newSet; - } - setMap.put(node, newSet); - } - - // In case the node is removed try { + // Initialize containerSet for node + if (!setMap.containsKey(node)) { + addNodeToSetMap(node); + } + // In case the node is removed nodeManager.getContainers(node); } catch (NodeNotFoundException e) { LOG.warn("Could not find Datanode {} while selecting candidate " + "containers for Container Balancer.", node.toString(), e); setMap.remove(node); - return new TreeSet<>(); + return Collections.emptySet(); } NavigableSet containerIDSet = setMap.get(node); @@ -262,4 +253,12 @@ public void setSelectedContainers( this.selectedContainers = selectedContainers; } + + private void addNodeToSetMap(DatanodeDetails node) + throws NodeNotFoundException { + NavigableSet newSet = + new TreeSet<>(orderContainersByUsedBytes().reversed()); + newSet.addAll(nodeManager.getContainers(node)); + setMap.put(node, newSet); + } } 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 abbc50ac86a5..031fae495952 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 @@ -50,7 +50,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.NavigableSet; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; @@ -692,7 +691,7 @@ private long cancelMovesThatExceedTimeoutDuration() { * @return ContainerMoveSelection containing the selected target and container */ private ContainerMoveSelection matchSourceWithTarget(DatanodeDetails source) { - NavigableSet candidateContainers = + Set candidateContainers = selectionCriteria.getCandidateContainers(source, sizeScheduledForMoveInLatestIteration); From 968cde76979cf2773853edcb68c78a3822912913 Mon Sep 17 00:00:00 2001 From: Symious Date: Mon, 22 Jan 2024 17:02:05 +0800 Subject: [PATCH 03/11] HDDS-10160. Filter selected and excluded containers --- .../balancer/ContainerBalancerSelectionCriteria.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) 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 2d1ae594b0f8..2cd9d30fc016 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 @@ -258,7 +258,14 @@ private void addNodeToSetMap(DatanodeDetails node) throws NodeNotFoundException { NavigableSet newSet = new TreeSet<>(orderContainersByUsedBytes().reversed()); - newSet.addAll(nodeManager.getContainers(node)); + Set idSet = nodeManager.getContainers(node); + if (excludeContainers != null) { + idSet.removeAll(excludeContainers); + } + if (selectedContainers != null) { + idSet.removeAll(selectedContainers); + } + newSet.addAll(idSet); setMap.put(node, newSet); } } From 2f4ec855f36eb7982412997d1dfaed2dedc85d11 Mon Sep 17 00:00:00 2001 From: Symious Date: Tue, 23 Jan 2024 15:25:09 +0800 Subject: [PATCH 04/11] HDDS-10160. check on iteration --- .../balancer/AbstractFindTargetGreedy.java | 38 +++++++------- .../ContainerBalancerSelectionCriteria.java | 49 +++++++++---------- .../balancer/ContainerBalancerTask.java | 23 ++++++--- .../balancer/FindTargetStrategy.java | 5 +- 4 files changed, 60 insertions(+), 55 deletions(-) diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/balancer/AbstractFindTargetGreedy.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/balancer/AbstractFindTargetGreedy.java index 660452b2d8b0..dc2cc731342c 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/balancer/AbstractFindTargetGreedy.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/balancer/AbstractFindTargetGreedy.java @@ -96,7 +96,7 @@ private void setConfiguration(ContainerBalancerConfiguration conf) { * Find a {@link ContainerMoveSelection} consisting of a target and * container to move for a source datanode. Favours more under-utilized nodes. * @param source Datanode to find a target for - * @param candidateContainers Set of candidate containers satisfying + * @param container candidate container satisfying * selection criteria * {@link ContainerBalancerSelectionCriteria} * (DatanodeDetails, Long) method returns true if the size specified in the @@ -105,29 +105,27 @@ private void setConfiguration(ContainerBalancerConfiguration conf) { */ @Override public ContainerMoveSelection findTargetForContainerMove( - DatanodeDetails source, Set candidateContainers) { + DatanodeDetails source, ContainerID container) { sortTargetForSource(source); for (DatanodeUsageInfo targetInfo : potentialTargets) { DatanodeDetails target = targetInfo.getDatanodeDetails(); - for (ContainerID container : candidateContainers) { - Set replicas; - ContainerInfo containerInfo; - try { - replicas = containerManager.getContainerReplicas(container); - containerInfo = containerManager.getContainer(container); - } catch (ContainerNotFoundException e) { - logger.warn("Could not get Container {} from Container Manager for " + - "obtaining replicas in Container Balancer.", container, e); - continue; - } + Set replicas; + ContainerInfo containerInfo; + try { + replicas = containerManager.getContainerReplicas(container); + containerInfo = containerManager.getContainer(container); + } catch (ContainerNotFoundException e) { + logger.warn("Could not get Container {} from Container Manager for " + + "obtaining replicas in Container Balancer.", container, e); + return null; + } - if (replicas.stream().noneMatch( - replica -> replica.getDatanodeDetails().equals(target)) && - containerMoveSatisfiesPlacementPolicy(container, replicas, source, - target) && - canSizeEnterTarget(target, containerInfo.getUsedBytes())) { - return new ContainerMoveSelection(target, container); - } + if (replicas.stream().noneMatch( + replica -> replica.getDatanodeDetails().equals(target)) && + containerMoveSatisfiesPlacementPolicy(container, replicas, source, + target) && + canSizeEnterTarget(target, containerInfo.getUsedBytes())) { + return new ContainerMoveSelection(target, container); } } logger.info("Container Balancer could not find a target for " + 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 2cd9d30fc016..7411186f4669 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 @@ -84,19 +84,13 @@ private boolean isContainerReplicatingOrDeleting(ContainerID containerID) { } /** - * Gets containers that are suitable for moving based on the following - * required criteria: - * 1. Container must not be undergoing replication. - * 2. Container must not already be selected for balancing. - * 3. Container size should be closer to 5GB. - * 4. Container must not be in the configured exclude containers list. - * 5. Container should be closed. - * 6. If the {@link LegacyReplicationManager} is enabled, then the container should not be an EC container. - * @param node DatanodeDetails for which to find candidate containers. - * @return Set of candidate containers that satisfy the criteria. + * Get ContainerID Set for the Datanode, it will be returned as NavigableSet + * Since sorting will be time-consuming, the Set will be cached. + * + * @param node source datanode + * @return cached Navigable ContainerID Set */ - public Set getCandidateContainers( - DatanodeDetails node, long sizeMovedAlready) { + public Set getContainerIDSet(DatanodeDetails node) { try { // Initialize containerSet for node if (!setMap.containsKey(node)) { @@ -111,17 +105,7 @@ public Set getCandidateContainers( return Collections.emptySet(); } - NavigableSet containerIDSet = setMap.get(node); - if (excludeContainers != null) { - containerIDSet.removeAll(excludeContainers); - } - if (selectedContainers != null) { - containerIDSet.removeAll(selectedContainers); - } - - containerIDSet.removeIf( - containerID -> shouldBeExcluded(containerID, node, sizeMovedAlready)); - return containerIDSet; + return setMap.get(node); } /** @@ -176,7 +160,21 @@ private boolean isECContainerAndLegacyRMEnabled(ContainerInfo container) { && replicationManager.getConfig().isLegacyEnabled(); } - private boolean shouldBeExcluded(ContainerID containerID, + /** + * Gets containers that are suitable for moving based on the following + * required criteria: + * 1. Container must not be in ExcludedContainers. + * 2. Container must not be in SelectedContainers. + * 3. Container must not be undergoing replication. + * 4. Container must not already be selected for balancing. + * 5. Container size should be closer to 5GB. + * 6. Container must not be in the configured exclude containers list. + * 7. Container should be closed. + * 8. If the {@link LegacyReplicationManager} is enabled, then the container should not be an EC container. + * @param node DatanodeDetails for which to find candidate containers. + * @return Set of candidate containers that satisfy the criteria. + */ + public boolean shouldBeExcluded(ContainerID containerID, DatanodeDetails node, long sizeMovedAlready) { ContainerInfo container; try { @@ -186,7 +184,8 @@ private boolean shouldBeExcluded(ContainerID containerID, "candidate container. Excluding it.", containerID); return true; } - return !isContainerClosed(container, node) || isECContainerAndLegacyRMEnabled(container) || + return excludeContainers.contains(containerID) || selectedContainers.contains(containerID) || + !isContainerClosed(container, node) || isECContainerAndLegacyRMEnabled(container) || isContainerReplicatingOrDeleting(containerID) || !findSourceStrategy.canSizeLeaveSource(node, container.getUsedBytes()) || breaksMaxSizeToMoveLimit(container.containerID(), 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 031fae495952..284948d4e532 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 @@ -691,11 +691,10 @@ private long cancelMovesThatExceedTimeoutDuration() { * @return ContainerMoveSelection containing the selected target and container */ private ContainerMoveSelection matchSourceWithTarget(DatanodeDetails source) { - Set candidateContainers = - selectionCriteria.getCandidateContainers(source, - sizeScheduledForMoveInLatestIteration); + Set sourceContainerIDSet = + selectionCriteria.getContainerIDSet(source); - if (candidateContainers.isEmpty()) { + if (sourceContainerIDSet.isEmpty()) { if (LOG.isDebugEnabled()) { LOG.debug("ContainerBalancer could not find any candidate containers " + "for datanode {}", source.getUuidString()); @@ -707,9 +706,19 @@ private ContainerMoveSelection matchSourceWithTarget(DatanodeDetails source) { LOG.debug("ContainerBalancer is finding suitable target for source " + "datanode {}", source.getUuidString()); } - ContainerMoveSelection moveSelection = - findTargetStrategy.findTargetForContainerMove( - source, candidateContainers); + + ContainerMoveSelection moveSelection = null; + for (ContainerID containerId: sourceContainerIDSet) { + if (selectionCriteria.shouldBeExcluded(containerId, source, + sizeScheduledForMoveInLatestIteration)) { + continue; + } + moveSelection = findTargetStrategy.findTargetForContainerMove(source, + containerId); + if (moveSelection != null) { + break; + } + } if (moveSelection == null) { if (LOG.isDebugEnabled()) { diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/balancer/FindTargetStrategy.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/balancer/FindTargetStrategy.java index 17f6aa329dcb..a30d6250b546 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/balancer/FindTargetStrategy.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/balancer/FindTargetStrategy.java @@ -25,7 +25,6 @@ import javax.annotation.Nonnull; import java.util.Collection; import java.util.List; -import java.util.Set; /** * This interface can be used to implement strategies to find a target for a @@ -40,7 +39,7 @@ public interface FindTargetStrategy { * enter a potential target. * * @param source Datanode to find a target for - * @param candidateContainers Set of candidate containers satisfying + * @param candidateContainer candidate containers satisfying * selection criteria * {@link ContainerBalancerSelectionCriteria} * (DatanodeDetails, Long) method returns true if the size specified in the @@ -49,7 +48,7 @@ public interface FindTargetStrategy { * selected container */ ContainerMoveSelection findTargetForContainerMove( - DatanodeDetails source, Set candidateContainers); + DatanodeDetails source, ContainerID candidateContainer); /** * increase the Entering size of a candidate target data node. From 05c5a056e6bf6f4be9b3635e53df23fd1387d163 Mon Sep 17 00:00:00 2001 From: Symious Date: Wed, 24 Jan 2024 07:27:30 +0800 Subject: [PATCH 05/11] Remove containers from candidationContainerSet --- .../hdds/scm/container/balancer/ContainerBalancerTask.java | 3 +++ 1 file changed, 3 insertions(+) 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 284948d4e532..19e721e5d9c1 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 @@ -708,9 +708,11 @@ private ContainerMoveSelection matchSourceWithTarget(DatanodeDetails source) { } ContainerMoveSelection moveSelection = null; + Set toRemoveContainers = new HashSet<>(); for (ContainerID containerId: sourceContainerIDSet) { if (selectionCriteria.shouldBeExcluded(containerId, source, sizeScheduledForMoveInLatestIteration)) { + toRemoveContainers.add(containerId); continue; } moveSelection = findTargetStrategy.findTargetForContainerMove(source, @@ -719,6 +721,7 @@ private ContainerMoveSelection matchSourceWithTarget(DatanodeDetails source) { break; } } + sourceContainerIDSet.removeAll(toRemoveContainers); if (moveSelection == null) { if (LOG.isDebugEnabled()) { From 54d336f99457e7b066b30342093b7b3204f1b18b Mon Sep 17 00:00:00 2001 From: Symious Date: Wed, 24 Jan 2024 07:28:17 +0800 Subject: [PATCH 06/11] Remove containerId from candidateContainerSet --- .../hdds/scm/container/balancer/ContainerBalancerTask.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 19e721e5d9c1..9f35a6ab4844 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 @@ -708,11 +708,11 @@ private ContainerMoveSelection matchSourceWithTarget(DatanodeDetails source) { } ContainerMoveSelection moveSelection = null; - Set toRemoveContainers = new HashSet<>(); + Set toRemoveContainerIds = new HashSet<>(); for (ContainerID containerId: sourceContainerIDSet) { if (selectionCriteria.shouldBeExcluded(containerId, source, sizeScheduledForMoveInLatestIteration)) { - toRemoveContainers.add(containerId); + toRemoveContainerIds.add(containerId); continue; } moveSelection = findTargetStrategy.findTargetForContainerMove(source, @@ -721,7 +721,7 @@ private ContainerMoveSelection matchSourceWithTarget(DatanodeDetails source) { break; } } - sourceContainerIDSet.removeAll(toRemoveContainers); + sourceContainerIDSet.removeAll(toRemoveContainerIds); if (moveSelection == null) { if (LOG.isDebugEnabled()) { From 7f3b0853189e0f4b9a54a745328d78c6a4c92e8b Mon Sep 17 00:00:00 2001 From: Symious Date: Wed, 24 Jan 2024 14:36:49 +0800 Subject: [PATCH 07/11] HDDS-10160. Add comment --- .../hdds/scm/container/balancer/ContainerBalancerTask.java | 1 + 1 file changed, 1 insertion(+) 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 9f35a6ab4844..94e8cfd04a1a 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 @@ -721,6 +721,7 @@ private ContainerMoveSelection matchSourceWithTarget(DatanodeDetails source) { break; } } + // Update cached containerIDSet in setMap sourceContainerIDSet.removeAll(toRemoveContainerIds); if (moveSelection == null) { From 92c7ba08a5dbdb1c10b336de62c6923b4a91d8b7 Mon Sep 17 00:00:00 2001 From: Symious Date: Fri, 26 Jan 2024 14:49:02 +0800 Subject: [PATCH 08/11] HDDS-10160. Use isNodeRegistered --- .../ContainerBalancerSelectionCriteria.java | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 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 7411186f4669..05b1d7d9aa74 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 @@ -91,16 +91,25 @@ private boolean isContainerReplicatingOrDeleting(ContainerID containerID) { * @return cached Navigable ContainerID Set */ public Set getContainerIDSet(DatanodeDetails node) { + // Check if the node is registered at the beginning + if (!nodeManager.isNodeRegistered(node)) { + return Collections.emptySet(); + } + try { // Initialize containerSet for node - if (!setMap.containsKey(node)) { - addNodeToSetMap(node); - } - // In case the node is removed - nodeManager.getContainers(node); - } catch (NodeNotFoundException e) { - LOG.warn("Could not find Datanode {} while selecting candidate " + - "containers for Container Balancer.", node.toString(), e); + setMap.computeIfAbsent(node, n -> { + try { + addNodeToSetMap(n); + return setMap.get(n); + } catch (NodeNotFoundException e) { + LOG.warn("Could not find Datanode {} while selecting candidate " + + "containers for Container Balancer.", n.toString(), e); + return null; + } + }); + } catch (Exception e) { + LOG.error("An unexpected error occurred while processing the node.", e); setMap.remove(node); return Collections.emptySet(); } From 7b590d2a89d173a6f154be5180d3d3e2d05b0ef6 Mon Sep 17 00:00:00 2001 From: Symious Date: Fri, 26 Jan 2024 16:45:13 +0800 Subject: [PATCH 09/11] HDDS-10160. Implement MockNodeManager's isNodeRegistered() --- .../org/apache/hadoop/hdds/scm/container/MockNodeManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/MockNodeManager.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/MockNodeManager.java index 794dedceef06..480f82976f40 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/MockNodeManager.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/MockNodeManager.java @@ -786,7 +786,7 @@ public List processHeartbeat(DatanodeDetails datanodeDetails, @Override public Boolean isNodeRegistered( DatanodeDetails datanodeDetails) { - return false; + return healthyNodes.contains(datanodeDetails); } @Override From b2c3bcbd96b50e01d7472c30e94ea7308ca96dab Mon Sep 17 00:00:00 2001 From: Symious Date: Sat, 27 Jan 2024 00:09:46 +0800 Subject: [PATCH 10/11] HDDS-10160. Code cleaning --- .../ContainerBalancerSelectionCriteria.java | 48 +++++++------------ 1 file changed, 18 insertions(+), 30 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 05b1d7d9aa74..9ce7938a99fe 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 @@ -95,26 +95,9 @@ public Set getContainerIDSet(DatanodeDetails node) { if (!nodeManager.isNodeRegistered(node)) { return Collections.emptySet(); } - - try { - // Initialize containerSet for node - setMap.computeIfAbsent(node, n -> { - try { - addNodeToSetMap(n); - return setMap.get(n); - } catch (NodeNotFoundException e) { - LOG.warn("Could not find Datanode {} while selecting candidate " + - "containers for Container Balancer.", n.toString(), e); - return null; - } - }); - } catch (Exception e) { - LOG.error("An unexpected error occurred while processing the node.", e); - setMap.remove(node); - return Collections.emptySet(); - } - - return setMap.get(node); + Set containers = setMap.computeIfAbsent(node, + this::getCandidateContainers); + return containers != null ? containers : Collections.emptySet(); } /** @@ -262,18 +245,23 @@ public void setSelectedContainers( } - private void addNodeToSetMap(DatanodeDetails node) - throws NodeNotFoundException { + private NavigableSet getCandidateContainers(DatanodeDetails node) { NavigableSet newSet = new TreeSet<>(orderContainersByUsedBytes().reversed()); - Set idSet = nodeManager.getContainers(node); - if (excludeContainers != null) { - idSet.removeAll(excludeContainers); - } - if (selectedContainers != null) { - idSet.removeAll(selectedContainers); + try { + Set idSet = nodeManager.getContainers(node); + if (excludeContainers != null) { + idSet.removeAll(excludeContainers); + } + if (selectedContainers != null) { + idSet.removeAll(selectedContainers); + } + newSet.addAll(idSet); + return newSet; + } catch (NodeNotFoundException e) { + LOG.warn("Could not find Datanode {} while selecting candidate " + + "containers for Container Balancer.", node, e); + return null; } - newSet.addAll(idSet); - setMap.put(node, newSet); } } From 8c00ae7b2464a56d6567888dc35e89e18dff3921 Mon Sep 17 00:00:00 2001 From: Symious Date: Tue, 30 Jan 2024 15:28:15 +0800 Subject: [PATCH 11/11] HDDS-10160. Update comments --- .../ContainerBalancerSelectionCriteria.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 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 9ce7938a99fe..d9102a883294 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 @@ -155,16 +155,14 @@ private boolean isECContainerAndLegacyRMEnabled(ContainerInfo container) { /** * Gets containers that are suitable for moving based on the following * required criteria: - * 1. Container must not be in ExcludedContainers. - * 2. Container must not be in SelectedContainers. - * 3. Container must not be undergoing replication. - * 4. Container must not already be selected for balancing. - * 5. Container size should be closer to 5GB. - * 6. Container must not be in the configured exclude containers list. - * 7. Container should be closed. - * 8. If the {@link LegacyReplicationManager} is enabled, then the container should not be an EC container. + * 1. Container must not be undergoing replication. + * 2. Container must not already be selected for balancing. + * 3. Container size should be closer to 5GB. + * 4. Container must not be in the configured exclude containers list. + * 5. Container should be closed. + * 6. If the {@link LegacyReplicationManager} is enabled, then the container should not be an EC container. * @param node DatanodeDetails for which to find candidate containers. - * @return Set of candidate containers that satisfy the criteria. + * @return true if the container should be excluded, else false */ public boolean shouldBeExcluded(ContainerID containerID, DatanodeDetails node, long sizeMovedAlready) {