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 2021/12/14 12:32:57 UTC

[ozone] branch master updated: HDDS-6053. Fix too short container scrubber data scan interval. (#2875)

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 4d1b5da  HDDS-6053. Fix too short container scrubber data scan interval. (#2875)
4d1b5da is described below

commit 4d1b5da594449150cbff46b44f07d559cbbe69b6
Author: Gui Hecheng <ma...@tencent.com>
AuthorDate: Tue Dec 14 20:32:34 2021 +0800

    HDDS-6053. Fix too short container scrubber data scan interval. (#2875)
---
 .../ozoneimpl/ContainerScrubberConfiguration.java  | 65 ++++++++++++---
 .../ozone/container/ozoneimpl/OzoneContainer.java  | 11 +++
 .../TestContainerScrubberConfiguration.java        | 97 ++++++++++++++++++++++
 3 files changed, 162 insertions(+), 11 deletions(-)

diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/ozoneimpl/ContainerScrubberConfiguration.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/ozoneimpl/ContainerScrubberConfiguration.java
index da7d196..6dcefe8 100644
--- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/ozoneimpl/ContainerScrubberConfiguration.java
+++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/ozoneimpl/ContainerScrubberConfiguration.java
@@ -21,6 +21,11 @@ import org.apache.hadoop.hdds.conf.Config;
 import org.apache.hadoop.hdds.conf.ConfigGroup;
 import org.apache.hadoop.hdds.conf.ConfigTag;
 import org.apache.hadoop.hdds.conf.ConfigType;
+import org.apache.hadoop.hdds.conf.PostConstruct;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.time.Duration;
 
 /**
  * This class defines configuration parameters for container scrubber.
@@ -28,34 +33,50 @@ import org.apache.hadoop.hdds.conf.ConfigType;
 @ConfigGroup(prefix = "hdds.container.scrub")
 public class ContainerScrubberConfiguration {
 
+  private static final Logger LOG =
+      LoggerFactory.getLogger(ContainerScrubberConfiguration.class);
+
   // only for log
   public static final String HDDS_CONTAINER_SCRUB_ENABLED =
       "hdds.container.scrub.enabled";
+  public static final String METADATA_SCAN_INTERVAL_KEY =
+      "hdds.container.scrub.metadata.scan.interval";
+  public static final String DATA_SCAN_INTERVAL_KEY =
+      "hdds.container.scrub.data.scan.interval";
+  public static final String VOLUME_BYTES_PER_SECOND_KEY =
+      "hdds.container.scrub.volume.bytes.per.second";
+
+  public static final long METADATA_SCAN_INTERVAL_DEFAULT =
+      Duration.ofHours(3).toMillis();
+  public static final long DATA_SCAN_INTERVAL_DEFAULT =
+      Duration.ofDays(7).toMillis();
+  public static final long BANDWIDTH_PER_VOLUME_DEFAULT = 1048576;   // 1MB
 
   @Config(key = "enabled",
       type = ConfigType.BOOLEAN,
       defaultValue = "false",
       tags = {ConfigTag.STORAGE},
       description = "Config parameter to enable container scrubber.")
-  private boolean enabled;
+  private boolean enabled = false;
 
   @Config(key = "metadata.scan.interval",
       type = ConfigType.TIME,
       defaultValue = "3h",
       tags = {ConfigTag.STORAGE},
-      description = "Config parameter define time interval in milliseconds" +
-          " between two metadata scans by container scrubber.")
-  private long metadataScanInterval;
+      description = "Config parameter define time interval" +
+          " between two metadata scans by container scrubber." +
+          " Unit could be defined with postfix (ns,ms,s,m,h,d).")
+  private long metadataScanInterval = METADATA_SCAN_INTERVAL_DEFAULT;
 
   @Config(key = "data.scan.interval",
       type = ConfigType.TIME,
-      defaultValue = "1m",
+      defaultValue = "7d",
       tags = {ConfigTag.STORAGE},
       description = "Minimum time interval between two iterations of container"
           + " data scanning.  If an iteration takes less time than this, the"
-          + " scanner will wait before starting the next iteration."
-  )
-  private long dataScanInterval;
+          + " scanner will wait before starting the next iteration." +
+          " Unit could be defined with postfix (ns,ms,s,m,h,d).")
+  private long dataScanInterval = DATA_SCAN_INTERVAL_DEFAULT;
 
   @Config(key = "volume.bytes.per.second",
       type = ConfigType.LONG,
@@ -63,9 +84,31 @@ public class ContainerScrubberConfiguration {
       tags = {ConfigTag.STORAGE},
       description = "Config parameter to throttle I/O bandwidth used"
           + " by scrubber per volume.")
-
-  private long bandwidthPerVolume;
-
+  private long bandwidthPerVolume = BANDWIDTH_PER_VOLUME_DEFAULT;
+
+  @PostConstruct
+  public void validate() {
+    if (metadataScanInterval < 0) {
+      LOG.warn(METADATA_SCAN_INTERVAL_KEY +
+              " must be >= 0 and was set to {}. Defaulting to {}",
+          metadataScanInterval, METADATA_SCAN_INTERVAL_DEFAULT);
+      metadataScanInterval = METADATA_SCAN_INTERVAL_DEFAULT;
+    }
+
+    if (dataScanInterval < 0) {
+      LOG.warn(DATA_SCAN_INTERVAL_KEY +
+              " must be >= 0 and was set to {}. Defaulting to {}",
+          dataScanInterval, DATA_SCAN_INTERVAL_DEFAULT);
+      dataScanInterval = DATA_SCAN_INTERVAL_DEFAULT;
+    }
+
+    if (bandwidthPerVolume < 0) {
+      LOG.warn(VOLUME_BYTES_PER_SECOND_KEY +
+              " must be >= 0 and was set to {}. Defaulting to {}",
+          bandwidthPerVolume, BANDWIDTH_PER_VOLUME_DEFAULT);
+      bandwidthPerVolume = BANDWIDTH_PER_VOLUME_DEFAULT;
+    }
+  }
 
   public void setEnabled(boolean enabled) {
     this.enabled = enabled;
diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/ozoneimpl/OzoneContainer.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/ozoneimpl/OzoneContainer.java
index 0042913..d6c90d5 100644
--- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/ozoneimpl/OzoneContainer.java
+++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/ozoneimpl/OzoneContainer.java
@@ -66,6 +66,7 @@ import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.Maps;
 import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_BLOCK_DELETING_SERVICE_TIMEOUT;
 import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_BLOCK_DELETING_SERVICE_TIMEOUT_DEFAULT;
+import static org.apache.hadoop.ozone.container.ozoneimpl.ContainerScrubberConfiguration.VOLUME_BYTES_PER_SECOND_KEY;
 
 import org.apache.hadoop.util.Timer;
 import org.apache.ratis.grpc.GrpcTlsConfig;
@@ -253,6 +254,12 @@ public class OzoneContainer {
       }
       this.metadataScanner.start();
 
+      if (c.getBandwidthPerVolume() == 0L) {
+        LOG.warn(VOLUME_BYTES_PER_SECOND_KEY + " is set to 0, " +
+            "so background container data scanner will not start.");
+        return;
+      }
+
       dataScanners = new ArrayList<>();
       for (StorageVolume v : volumeSet.getVolumesList()) {
         ContainerDataScanner s = new ContainerDataScanner(c, controller,
@@ -272,6 +279,10 @@ public class OzoneContainer {
     }
     metadataScanner.shutdown();
     metadataScanner = null;
+
+    if (dataScanners == null) {
+      return;
+    }
     for (ContainerDataScanner s : dataScanners) {
       s.shutdown();
     }
diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/ozoneimpl/TestContainerScrubberConfiguration.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/ozoneimpl/TestContainerScrubberConfiguration.java
new file mode 100644
index 0000000..af2bc80
--- /dev/null
+++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/ozoneimpl/TestContainerScrubberConfiguration.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.ozone.container.ozoneimpl;
+
+import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.hdds.conf.StorageUnit;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.time.Duration;
+
+import static org.apache.hadoop.ozone.container.ozoneimpl.ContainerScrubberConfiguration.BANDWIDTH_PER_VOLUME_DEFAULT;
+import static org.apache.hadoop.ozone.container.ozoneimpl.ContainerScrubberConfiguration.DATA_SCAN_INTERVAL_DEFAULT;
+import static org.apache.hadoop.ozone.container.ozoneimpl.ContainerScrubberConfiguration.DATA_SCAN_INTERVAL_KEY;
+import static org.apache.hadoop.ozone.container.ozoneimpl.ContainerScrubberConfiguration.METADATA_SCAN_INTERVAL_DEFAULT;
+import static org.apache.hadoop.ozone.container.ozoneimpl.ContainerScrubberConfiguration.METADATA_SCAN_INTERVAL_KEY;
+import static org.apache.hadoop.ozone.container.ozoneimpl.ContainerScrubberConfiguration.VOLUME_BYTES_PER_SECOND_KEY;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test for {@link ContainerScrubberConfiguration}.
+ */
+public class TestContainerScrubberConfiguration {
+
+  private OzoneConfiguration conf;
+
+  @Before
+  public void setup() {
+    this.conf = new OzoneConfiguration();
+  }
+
+  @Test
+  public void acceptsValidValues() {
+    long validInterval = Duration.ofHours(1).toMillis();
+    long validBandwidth = (long) StorageUnit.MB.toBytes(1);
+
+    conf.setLong(METADATA_SCAN_INTERVAL_KEY, validInterval);
+    conf.setLong(DATA_SCAN_INTERVAL_KEY, validInterval);
+    conf.setLong(VOLUME_BYTES_PER_SECOND_KEY, validBandwidth);
+
+    ContainerScrubberConfiguration csConf =
+        conf.getObject(ContainerScrubberConfiguration.class);
+
+    assertEquals(validInterval, csConf.getMetadataScanInterval());
+    assertEquals(validInterval, csConf.getDataScanInterval());
+    assertEquals(validBandwidth, csConf.getBandwidthPerVolume());
+  }
+
+  @Test
+  public void overridesInvalidValues() {
+    long invalidInterval = -1;
+    long invalidBandwidth = -1;
+
+    conf.setLong(METADATA_SCAN_INTERVAL_KEY, invalidInterval);
+    conf.setLong(DATA_SCAN_INTERVAL_KEY, invalidInterval);
+    conf.setLong(VOLUME_BYTES_PER_SECOND_KEY, invalidBandwidth);
+
+    ContainerScrubberConfiguration csConf =
+        conf.getObject(ContainerScrubberConfiguration.class);
+
+    assertEquals(METADATA_SCAN_INTERVAL_DEFAULT,
+        csConf.getMetadataScanInterval());
+    assertEquals(DATA_SCAN_INTERVAL_DEFAULT,
+        csConf.getDataScanInterval());
+    assertEquals(BANDWIDTH_PER_VOLUME_DEFAULT,
+        csConf.getBandwidthPerVolume());
+  }
+
+  @Test
+  public void isCreatedWitDefaultValues() {
+    ContainerScrubberConfiguration csConf =
+        conf.getObject(ContainerScrubberConfiguration.class);
+
+    assertEquals(false, csConf.isEnabled());
+    assertEquals(METADATA_SCAN_INTERVAL_DEFAULT,
+        csConf.getMetadataScanInterval());
+    assertEquals(DATA_SCAN_INTERVAL_DEFAULT,
+        csConf.getDataScanInterval());
+    assertEquals(BANDWIDTH_PER_VOLUME_DEFAULT,
+        csConf.getBandwidthPerVolume());
+  }
+}

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