diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/impl/ChunkManagerFactory.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/impl/ChunkManagerFactory.java index 046bfddfaee..673e2896830 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/impl/ChunkManagerFactory.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/impl/ChunkManagerFactory.java @@ -20,7 +20,6 @@ package org.apache.hadoop.ozone.container.keyvalue.impl; import com.google.common.base.Preconditions; import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.hdds.HddsConfigKeys; import org.apache.hadoop.ozone.container.keyvalue.interfaces.ChunkManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/ozoneimpl/ContainerDataScanner.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/ozoneimpl/ContainerDataScanner.java index 2b0f3f33776..799c8fed368 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/ozoneimpl/ContainerDataScanner.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/ozoneimpl/ContainerDataScanner.java @@ -19,7 +19,10 @@ package org.apache.hadoop.ozone.container.ozoneimpl; import java.io.IOException; import java.util.Iterator; +import java.util.concurrent.TimeUnit; +import com.google.common.annotations.VisibleForTesting; +import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hdfs.util.Canceler; import org.apache.hadoop.hdfs.util.DataTransferThrottler; import org.apache.hadoop.ozone.container.common.interfaces.Container; @@ -42,6 +45,7 @@ public class ContainerDataScanner extends Thread { private final ContainerController controller; private final DataTransferThrottler throttler; private final Canceler canceler; + private final ContainerDataScrubberMetrics metrics; /** * True if the thread is stopping.
@@ -50,12 +54,15 @@ public class ContainerDataScanner extends Thread { private volatile boolean stopping = false; - public ContainerDataScanner(ContainerController controller, + public ContainerDataScanner(Configuration conf, + ContainerController controller, HddsVolume volume, long bytesPerSec) { this.controller = controller; this.volume = volume; - this.throttler = new DataTransferThrottler(bytesPerSec); + this.throttler = new HddsDataTransferThrottler(bytesPerSec); this.canceler = new Canceler(); + this.metrics = ContainerDataScrubberMetrics.create(conf, + volume.toString()); setName("ContainerDataScanner(" + volume + ")"); setDaemon(true); } @@ -65,26 +72,54 @@ public class ContainerDataScanner extends Thread { LOG.trace("{}: thread starting.", this); try { while (!stopping) { - Iterator+ * http://www.apache.org/licenses/LICENSE-2.0 + *
+ * 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.hdfs.util.Canceler;
+import org.apache.hadoop.hdfs.util.DataTransferThrottler;
+import org.apache.hadoop.ozone.container.common.impl.ContainerData;
+import org.apache.hadoop.ozone.container.common.interfaces.Container;
+import org.apache.hadoop.ozone.container.common.volume.HddsVolume;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.util.Iterator;
+
+/**
+ * This test verifies the container scrubber metrics functionality.
+ */
+public class TestContainerScrubberMetrics {
+ @Test
+ public void testContainerMetaDataScrubberMetrics() {
+ OzoneConfiguration conf = new OzoneConfiguration();
+ ContainerScrubberConfiguration c = conf.getObject(
+ ContainerScrubberConfiguration.class);
+ c.setMetadataScanInterval(0);
+ HddsVolume vol = Mockito.mock(HddsVolume.class);
+ ContainerController cntrl = mockContainerController(vol);
+
+ ContainerMetadataScanner mc = new ContainerMetadataScanner(conf,
+ cntrl, c.getMetadataScanInterval());
+ mc.runIteration();
+
+ Assert.assertEquals(1, mc.getMetrics().getNumScanIterations());
+ Assert.assertEquals(3, mc.getMetrics().getNumContainersScanned());
+ Assert.assertEquals(1, mc.getMetrics().getNumUnHealthyContainers());
+ }
+
+ @Test
+ public void testContainerDataScrubberMetrics() {
+ OzoneConfiguration conf = new OzoneConfiguration();
+ ContainerScrubberConfiguration c = conf.getObject(
+ ContainerScrubberConfiguration.class);
+ HddsVolume vol = Mockito.mock(HddsVolume.class);
+ ContainerController cntrl = mockContainerController(vol);
+
+ ContainerDataScanner sc = new ContainerDataScanner(conf, cntrl,
+ vol, c.getBandwidthPerVolume());
+ sc.runIteration();
+
+ ContainerDataScrubberMetrics m = sc.getMetrics();
+ Assert.assertEquals(1, m.getNumScanIterations());
+ Assert.assertEquals(2, m.getNumContainersScanned());
+ Assert.assertEquals(1, m.getNumUnHealthyContainers());
+ }
+
+ private ContainerController mockContainerController(HddsVolume vol) {
+ // healthy container
+ Container c1 = Mockito.mock(Container.class);
+ Mockito.when(c1.shouldScanData()).thenReturn(true);
+ Mockito.when(c1.scanMetaData()).thenReturn(true);
+ Mockito.when(c1.scanData(
+ Mockito.any(DataTransferThrottler.class),
+ Mockito.any(Canceler.class))).thenReturn(true);
+
+ // unhealthy container (corrupt data)
+ ContainerData c2d = Mockito.mock(ContainerData.class);
+ Mockito.when(c2d.getContainerID()).thenReturn(101L);
+ Container c2 = Mockito.mock(Container.class);
+ Mockito.when(c2.scanMetaData()).thenReturn(true);
+ Mockito.when(c2.shouldScanData()).thenReturn(true);
+ Mockito.when(c2.scanData(
+ Mockito.any(DataTransferThrottler.class),
+ Mockito.any(Canceler.class))).thenReturn(false);
+ Mockito.when(c2.getContainerData()).thenReturn(c2d);
+
+ // unhealthy container (corrupt metadata)
+ ContainerData c3d = Mockito.mock(ContainerData.class);
+ Mockito.when(c3d.getContainerID()).thenReturn(102L);
+ Container c3 = Mockito.mock(Container.class);
+ Mockito.when(c3.shouldScanData()).thenReturn(false);
+ Mockito.when(c3.scanMetaData()).thenReturn(false);
+ Mockito.when(c3.getContainerData()).thenReturn(c3d);
+
+ Iterator