You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ozone.apache.org by er...@apache.org on 2021/10/25 23:57:59 UTC

[ozone] branch ozone-1.2 updated: HDDS-5843. SCM terminates when adding container to a pipeline during startup (#2745)

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

erose pushed a commit to branch ozone-1.2
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/ozone-1.2 by this push:
     new d1d03e3  HDDS-5843. SCM terminates when adding container to a pipeline during startup (#2745)
d1d03e3 is described below

commit d1d03e3b2cb82c82e8d97e5dd8aa575f237ff4e2
Author: Aswin Shakil Balasubramanian <as...@gmail.com>
AuthorDate: Mon Oct 25 16:41:04 2021 -0700

    HDDS-5843. SCM terminates when adding container to a pipeline during startup (#2745)
---
 .../scm/container/ContainerStateManagerImpl.java   |  4 ++--
 .../hadoop/hdds/scm/pipeline/PipelineManager.java  | 10 ++++++++
 .../hdds/scm/pipeline/PipelineManagerImpl.java     |  7 ++++++
 .../hdds/scm/pipeline/PipelineStateManager.java    |  5 ++++
 .../scm/pipeline/PipelineStateManagerImpl.java     | 12 ++++++++++
 .../hadoop/hdds/scm/pipeline/PipelineStateMap.java | 27 ++++++++++++++++++++++
 .../hdds/scm/pipeline/MockPipelineManager.java     |  6 +++++
 .../hdds/scm/pipeline/TestPipelineManagerImpl.java | 26 +++++++++++++++++++++
 8 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerStateManagerImpl.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerStateManagerImpl.java
index 2abc6d0..4777d49 100644
--- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerStateManagerImpl.java
+++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerStateManagerImpl.java
@@ -229,8 +229,8 @@ public final class ContainerStateManagerImpl
       containers.addContainer(container);
       if (container.getState() == LifeCycleState.OPEN) {
         try {
-          pipelineManager.addContainerToPipeline(container.getPipelineID(),
-              container.containerID());
+          pipelineManager.addContainerToPipelineSCMStart(
+              container.getPipelineID(), container.containerID());
         } catch (PipelineNotFoundException ex) {
           LOG.warn("Found container {} which is in OPEN state with " +
                   "pipeline {} that does not exist. Marking container for " +
diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineManager.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineManager.java
index ff30c2b..b96d616 100644
--- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineManager.java
+++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineManager.java
@@ -68,6 +68,16 @@ public interface PipelineManager extends Closeable, PipelineManagerMXBean {
   void addContainerToPipeline(PipelineID pipelineID, ContainerID containerID)
       throws IOException;
 
+  /**
+   * Add container to pipeline during SCM Start.
+   *
+   * @param pipelineID ID of the pipeline to which container is added.
+   * @param containerID ID of the container which is added to the pipeline.
+   * @throws IOException in case of any Exception
+   */
+  void addContainerToPipelineSCMStart(PipelineID pipelineID,
+      ContainerID containerID) throws IOException;
+
   void removeContainerFromPipeline(PipelineID pipelineID,
       ContainerID containerID) throws IOException;
 
diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineManagerImpl.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineManagerImpl.java
index 8d37144..04d03b7 100644
--- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineManagerImpl.java
+++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineManagerImpl.java
@@ -253,6 +253,13 @@ public class PipelineManagerImpl implements PipelineManager {
   }
 
   @Override
+  public void addContainerToPipelineSCMStart(
+      PipelineID pipelineID, ContainerID containerID) throws IOException {
+    // should not lock here, since no ratis operation happens.
+    stateManager.addContainerToPipelineSCMStart(pipelineID, containerID);
+  }
+
+  @Override
   public void removeContainerFromPipeline(
       PipelineID pipelineID, ContainerID containerID) throws IOException {
     // should not lock here, since no ratis operation happens.
diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineStateManager.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineStateManager.java
index ed4ddde..4af64b5 100644
--- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineStateManager.java
+++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineStateManager.java
@@ -70,6 +70,11 @@ public interface PipelineStateManager {
       ContainerID containerID
   ) throws IOException;
 
+  void addContainerToPipelineSCMStart(
+      PipelineID pipelineID,
+      ContainerID containerID
+  ) throws IOException;
+
   Pipeline getPipeline(PipelineID pipelineID) throws PipelineNotFoundException;
 
   List<Pipeline> getPipelines();
diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineStateManagerImpl.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineStateManagerImpl.java
index c9b1d77..9589eb9 100644
--- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineStateManagerImpl.java
+++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineStateManagerImpl.java
@@ -118,6 +118,18 @@ public class PipelineStateManagerImpl implements PipelineStateManager {
   }
 
   @Override
+  public void addContainerToPipelineSCMStart(
+          PipelineID pipelineId, ContainerID containerID)
+          throws IOException {
+    lock.writeLock().lock();
+    try {
+      pipelineStateMap.addContainerToPipelineSCMStart(pipelineId, containerID);
+    } finally {
+      lock.writeLock().unlock();
+    }
+  }
+
+  @Override
   public Pipeline getPipeline(PipelineID pipelineID)
       throws PipelineNotFoundException {
     lock.readLock().lock();
diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineStateMap.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineStateMap.java
index 4a68c80..0e98925 100644
--- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineStateMap.java
+++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineStateMap.java
@@ -105,6 +105,33 @@ class PipelineStateMap {
   }
 
   /**
+   * Add container to an existing pipeline during SCM Start.
+   *
+   * @param pipelineID - PipelineID of the pipeline to which container is added
+   * @param containerID - ContainerID of the container to add
+   */
+  void addContainerToPipelineSCMStart(PipelineID pipelineID,
+      ContainerID containerID) throws IOException {
+    Preconditions.checkNotNull(pipelineID,
+            "Pipeline Id cannot be null");
+    Preconditions.checkNotNull(containerID,
+            "Container Id cannot be null");
+
+    Pipeline pipeline = getPipeline(pipelineID);
+    if (pipeline.isClosed()) {
+      /*
+      When SCM restarts,the SCM DB may not be upto date where some
+      containers are in an OPEN state for a CLOSED pipeline. This happens when
+      close pipeline transaction in flushed before SCM goes down and close
+      container is not flushed into DB.
+      */
+      LOG.info("Container {} in open state for pipeline={} in closed state",
+              containerID, pipelineID);
+    }
+    pipeline2container.get(pipelineID).add(containerID);
+  }
+
+  /**
    * Get pipeline corresponding to specified pipelineID.
    *
    * @param pipelineID - PipelineID of the pipeline to be retrieved
diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/pipeline/MockPipelineManager.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/pipeline/MockPipelineManager.java
index b155f28..cf3e84b 100644
--- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/pipeline/MockPipelineManager.java
+++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/pipeline/MockPipelineManager.java
@@ -133,6 +133,12 @@ public final class MockPipelineManager implements PipelineManager {
   }
 
   @Override
+  public void addContainerToPipelineSCMStart(
+          PipelineID pipelineID, ContainerID containerID) throws IOException {
+    stateManager.addContainerToPipelineSCMStart(pipelineID, containerID);
+  }
+
+  @Override
   public void removeContainerFromPipeline(final PipelineID pipelineID,
                                           final ContainerID containerID)
       throws IOException {
diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/pipeline/TestPipelineManagerImpl.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/pipeline/TestPipelineManagerImpl.java
index d76df1e..a2ec1cf 100644
--- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/pipeline/TestPipelineManagerImpl.java
+++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/pipeline/TestPipelineManagerImpl.java
@@ -49,6 +49,7 @@ import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
+import org.slf4j.LoggerFactory;
 
 import java.io.File;
 import java.io.IOException;
@@ -63,6 +64,7 @@ import static org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_PIPELINE_ALLOCA
 import static org.apache.hadoop.hdds.scm.pipeline.Pipeline.PipelineState.ALLOCATED;
 import static org.apache.hadoop.test.MetricsAsserts.getLongCounter;
 import static org.apache.hadoop.test.MetricsAsserts.getMetrics;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 /**
@@ -624,6 +626,30 @@ public class TestPipelineManagerImpl {
     pipelineManager.close();
   }
 
+  @Test
+  public void testAddContainerWithClosedPipeline() throws Exception {
+    GenericTestUtils.LogCapturer logCapturer = GenericTestUtils.LogCapturer.
+            captureLogs(LoggerFactory.getLogger(PipelineStateMap.class));
+    SCMHADBTransactionBuffer buffer = new MockSCMHADBTransactionBuffer(dbStore);
+    PipelineManagerImpl pipelineManager =
+            createPipelineManager(true, buffer);
+    Table<PipelineID, Pipeline> pipelineStore =
+            SCMDBDefinition.PIPELINES.getTable(dbStore);
+    Pipeline pipeline = pipelineManager.createPipeline(
+            new RatisReplicationConfig(HddsProtos.ReplicationFactor.THREE));
+    PipelineID pipelineID = pipeline.getId();
+    pipelineManager.addContainerToPipeline(pipelineID, ContainerID.valueOf(1));
+    pipelineManager.getStateManager().updatePipelineState(
+            pipelineID.getProtobuf(), HddsProtos.PipelineState.PIPELINE_CLOSED);
+    buffer.flush();
+    Assert.assertTrue(pipelineStore.get(pipelineID).isClosed());
+    pipelineManager.addContainerToPipelineSCMStart(pipelineID,
+            ContainerID.valueOf(2));
+    assertTrue(logCapturer.getOutput().contains("Container " +
+            ContainerID.valueOf(2) + " in open state for pipeline=" +
+            pipelineID + " in closed state"));
+  }
+
   private void sendPipelineReport(
       DatanodeDetails dn, Pipeline pipeline,
       PipelineReportHandler pipelineReportHandler,

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