This is an automated email from the ASF dual-hosted git repository.
smengcl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/master by this push:
new 80ffb62a841 HDDS-16066. replicas after re-replication should span at
least 2 racks (#10944)
80ffb62a841 is described below
commit 80ffb62a8413f87cd75c19390c729f0ed53ed421
Author: Han-Wen Hsu <[email protected]>
AuthorDate: Mon Aug 10 04:00:41 2026 +0800
HDDS-16066. replicas after re-replication should span at least 2 racks
(#10944)
---
.../dev-support/findbugsExcludeFile.xml | 12 -----
.../hadoop/hdds/scm/TestRackAwarePlacement.java | 58 ++++++++++++++++------
2 files changed, 42 insertions(+), 28 deletions(-)
diff --git a/hadoop-ozone/integration-test/dev-support/findbugsExcludeFile.xml
b/hadoop-ozone/integration-test/dev-support/findbugsExcludeFile.xml
index bbc0b6b17af..55abc263017 100644
--- a/hadoop-ozone/integration-test/dev-support/findbugsExcludeFile.xml
+++ b/hadoop-ozone/integration-test/dev-support/findbugsExcludeFile.xml
@@ -16,16 +16,4 @@
limitations under the License.
-->
<FindBugsFilter>
- <Match>
- <Class
name="org.apache.hadoop.hdds.scm.TestRackAwarePlacement$WithRacksAndHosts"/>
- <Bug pattern="SIC_INNER_SHOULD_BE_STATIC"/>
- </Match>
- <Match>
- <Class
name="org.apache.hadoop.hdds.scm.TestRackAwarePlacement$WithRacksOnly"/>
- <Bug pattern="SIC_INNER_SHOULD_BE_STATIC"/>
- </Match>
- <Match>
- <Class
name="org.apache.hadoop.hdds.scm.TestRackAwarePlacement$WithHostsOnly"/>
- <Bug pattern="SIC_INNER_SHOULD_BE_STATIC"/>
- </Match>
</FindBugsFilter>
diff --git
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/hdds/scm/TestRackAwarePlacement.java
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/hdds/scm/TestRackAwarePlacement.java
index c8258eb0e43..6df252fdc79 100644
---
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/hdds/scm/TestRackAwarePlacement.java
+++
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/hdds/scm/TestRackAwarePlacement.java
@@ -28,6 +28,7 @@
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.hadoop.hdds.client.RatisReplicationConfig;
@@ -287,7 +288,9 @@ private static void assertContainerReplicationIsRackAware(
for (ContainerInfo c : scm.getContainerManager().getContainers()) {
Set<ContainerReplica> r =
scm.getContainerManager().getContainerReplicas(c.containerID());
- if (r.size() >= 3) {
+ // Start with a normally replicated container so stopping one datanode
+ // must trigger creation of a replacement replica.
+ if (r.size() == 3) {
targetContainer = c;
replicas = r;
break;
@@ -311,29 +314,52 @@ private static void assertContainerReplicationIsRackAware(
}
}, 500, 30_000);
+ waitForRackAwareReplication(scm, containerID, stoppedDn);
+
+ Set<String> racks = getReplicaRacks(scm.getContainerManager()
+ .getContainerReplicas(containerID));
+
+ assertTrue(racks.size() >= 2,
+ "Container replicas after re-replication should span at least "
+ + "2 racks, but were on: " + racks);
+ }
+
+ private static void waitForRackAwareReplication(
+ StorageContainerManager scm, ContainerID containerID,
+ DatanodeDetails stoppedDn)
+ throws TimeoutException, InterruptedException {
GenericTestUtils.waitFor(() -> {
try {
- return scm.getContainerManager()
- .getContainerReplicas(containerID)
- .size() >= 3;
+ Set<ContainerReplica> current = scm.getContainerManager()
+ .getContainerReplicas(containerID);
+
+ // Starting with exactly 3 replicas ensures that removing the dead
+ // replica requires a replacement. Use >= here to allow temporary
+ // over-replication while placement repair converges.
+ boolean deadReplicaRemoved = current.stream()
+ .noneMatch(replica -> stoppedDn.equals(
+ replica.getDatanodeDetails()));
+ boolean replicaCountRestored = current.size() >= 3;
+ boolean rackAware = getReplicaRacks(current).size() >= 2;
+
+ // Replica reports and placement repair are asynchronous. Wait for the
+ // replacement and the resulting rack-aware placement to be visible.
+ return deadReplicaRemoved && replicaCountRestored && rackAware;
} catch (Exception e) {
return false;
}
}, 1_000, 60_000);
+ }
- Set<String> racks = scm.getContainerManager()
- .getContainerReplicas(containerID)
- .stream()
- .map(r -> r.getDatanodeDetails().getNetworkLocation())
+ private static Set<String> getReplicaRacks(
+ Set<ContainerReplica> replicas) {
+ return replicas.stream()
+ .map(replica -> replica.getDatanodeDetails().getNetworkLocation())
.collect(Collectors.toSet());
-
- assertTrue(racks.size() >= 2,
- "Container replicas after re-replication should span at least "
- + "2 racks, but were on: " + racks);
}
- private static void assertRackAssignments(MiniOzoneCluster cluster,
- String[] expectedRacks) {
+ private void assertRackAssignments(MiniOzoneCluster cluster,
+ String[] expectedRacks) {
NodeManager nodeManager =
cluster.getStorageContainerManager().getScmNodeManager();
List<? extends DatanodeDetails> allNodes = nodeManager.getAllNodes();
@@ -368,8 +394,8 @@ private static void assertRackAssignments(MiniOzoneCluster
cluster,
}
}
- private static void assertHostnameAssignments(MiniOzoneCluster cluster,
- String[] expectedHosts) {
+ private void assertHostnameAssignments(MiniOzoneCluster cluster,
+ String[] expectedHosts) {
NodeManager nodeManager =
cluster.getStorageContainerManager().getScmNodeManager();
List<? extends DatanodeDetails> allNodes = nodeManager.getAllNodes();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]