You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ozone.apache.org by ad...@apache.org on 2023/04/21 13:26:08 UTC

[ozone] branch master updated: HDDS-8416. ReplicationManager: RatisUnderReplicationHandler should filter sources by highest BCSID (#4599)

This is an automated email from the ASF dual-hosted git repository.

adoroszlai 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 99bab79cef HDDS-8416. ReplicationManager: RatisUnderReplicationHandler should filter sources by highest BCSID (#4599)
99bab79cef is described below

commit 99bab79cefed1c522035af06d025aeeafa11c54a
Author: Stephen O'Donnell <st...@gmail.com>
AuthorDate: Fri Apr 21 14:26:02 2023 +0100

    HDDS-8416. ReplicationManager: RatisUnderReplicationHandler should filter sources by highest BCSID (#4599)
---
 .../replication/RatisUnderReplicationHandler.java  | 30 ++++++++++++++++++----
 .../TestRatisUnderReplicationHandler.java          | 20 +++++++++++++++
 2 files changed, 45 insertions(+), 5 deletions(-)

diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/RatisUnderReplicationHandler.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/RatisUnderReplicationHandler.java
index cac0be0ee3..75bd8c4c41 100644
--- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/RatisUnderReplicationHandler.java
+++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/RatisUnderReplicationHandler.java
@@ -36,9 +36,11 @@ import org.slf4j.LoggerFactory;
 import java.io.IOException;
 import java.util.HashSet;
 import java.util.List;
+import java.util.OptionalLong;
 import java.util.Set;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * This class handles Ratis containers that are under replicated. It should
@@ -203,10 +205,10 @@ public class RatisUnderReplicationHandler
 
     /*
      * Return healthy datanodes which have a replica that satisfies the
-     * predicate and is not pending replica deletion. Sorted in descending
-     * order of sequence id.
+     * predicate and is not pending replica deletion
      */
-    return replicaCount.getReplicas().stream()
+    List<ContainerReplica> availableSources = replicaCount.getReplicas()
+        .stream()
         .filter(predicate)
         .filter(r -> {
           try {
@@ -217,8 +219,26 @@ public class RatisUnderReplicationHandler
           }
         })
         .filter(r -> !pendingDeletion.contains(r.getDatanodeDetails()))
-        .sorted((r1, r2) -> r2.getSequenceId().compareTo(r1.getSequenceId()))
-        .map(ContainerReplica::getDatanodeDetails)
+        .collect(Collectors.toList());
+
+    // We should replicate only the max available sequence ID, as replicas with
+    // earlier sequence IDs may be stale copies.
+    // First we get the max sequence ID, if there is at least one replica with
+    // a non-null sequence.
+    OptionalLong maxSequenceId = availableSources.stream()
+        .filter(r -> r.getSequenceId() != null)
+        .mapToLong(ContainerReplica::getSequenceId)
+        .max();
+
+    // Filter out all but the max sequence ID, or keep all if there is no
+    // max.
+    Stream<ContainerReplica> replicaStream = availableSources.stream();
+    if (maxSequenceId.isPresent()) {
+      replicaStream = replicaStream
+          .filter(r -> r.getSequenceId() != null)
+          .filter(r -> r.getSequenceId() == maxSequenceId.getAsLong());
+    }
+    return replicaStream.map(ContainerReplica::getDatanodeDetails)
         .collect(Collectors.toList());
   }
 
diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestRatisUnderReplicationHandler.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestRatisUnderReplicationHandler.java
index 299e0e16e0..0cf3a8a8b5 100644
--- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestRatisUnderReplicationHandler.java
+++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestRatisUnderReplicationHandler.java
@@ -55,6 +55,7 @@ import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeOperationalSt
 import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeOperationalState.IN_SERVICE;
 import static org.apache.hadoop.hdds.scm.container.replication.ReplicationTestUtil.createContainerReplica;
 import static org.apache.hadoop.hdds.scm.container.replication.ReplicationTestUtil.createReplicas;
+import static org.mockito.ArgumentMatchers.anyInt;
 
 /**
  * Tests for {@link RatisUnderReplicationHandler}.
@@ -262,6 +263,25 @@ public class TestRatisUnderReplicationHandler {
     Assert.assertEquals(closedReplica.getDatanodeDetails(), command.getKey());
   }
 
+  @Test
+  public void testOnlyHighestBcsidShouldBeASource() throws IOException {
+    Set<ContainerReplica> replicas = new HashSet<>();
+    replicas.add(createContainerReplica(container.containerID(), 0,
+        IN_SERVICE, State.CLOSED, 1));
+    ContainerReplica valid = createContainerReplica(
+        container.containerID(), 0, IN_SERVICE, State.CLOSED, 2);
+    replicas.add(valid);
+
+    testProcessing(replicas, Collections.emptyList(),
+        getUnderReplicatedHealthResult(), 2, 1);
+
+    // Ensure that the replica with SEQ=2 is the only source sent
+    Mockito.verify(replicationManager).sendThrottledReplicationCommand(
+        Mockito.any(ContainerInfo.class),
+        Mockito.eq(Collections.singletonList(valid.getDatanodeDetails())),
+        Mockito.any(DatanodeDetails.class), anyInt());
+  }
+
   /**
    * Tests whether the specified expectNumCommands number of commands are
    * created by the handler.


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@ozone.apache.org
For additional commands, e-mail: commits-help@ozone.apache.org