You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ozone.apache.org by el...@apache.org on 2020/08/01 05:38:45 UTC

[hadoop-ozone] branch master updated: HDDS-4021. Organize Recon DBs into a 'DBDefinition'. (#1255)

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

elek pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hadoop-ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new e219aae  HDDS-4021. Organize Recon DBs into a 'DBDefinition'. (#1255)
e219aae is described below

commit e219aae7c7bcd8eacd592ca2ccfcf58626477f37
Author: avijayanhwx <14...@users.noreply.github.com>
AuthorDate: Fri Jul 31 22:38:34 2020 -0700

    HDDS-4021. Organize Recon DBs into a 'DBDefinition'. (#1255)
---
 .../DatanodeDetailsCodec.java}                     | 29 ++++++---
 .../ReconNodeDBKeyCodec.java}                      | 26 +++++---
 .../package-info.java}                             | 28 ++-------
 .../hadoop/ozone/recon/scm/ReconNodeManager.java   | 55 ++++-------------
 ...DBDefinition.java => ReconSCMDBDefinition.java} | 29 ++++++++-
 .../scm/ReconStorageContainerManagerFacade.java    |  9 +--
 .../spi/impl/ContainerDBServiceProviderImpl.java   | 29 ++++-----
 .../recon/spi/impl/ReconContainerDBProvider.java   | 28 +++------
 .../ozone/recon/spi/impl/ReconDBDefinition.java    | 71 ++++++++++++++++++++++
 .../scm/AbstractReconContainerManagerTest.java     |  6 +-
 .../ozone/recon/scm/TestReconNodeManager.java      | 20 +++++-
 .../ozone/recon/scm/TestReconPipelineManager.java  |  8 +--
 hadoop-ozone/tools/pom.xml                         |  4 ++
 .../hadoop/ozone/debug/DBDefinitionFactory.java    | 22 ++++++-
 .../org/apache/hadoop/ozone/debug/DBScanner.java   | 25 ++++++--
 .../ozone/debug/TestDBDefinitionFactory.java       | 59 ++++++++++++++++++
 16 files changed, 303 insertions(+), 145 deletions(-)

diff --git a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconDBDefinition.java b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/codec/DatanodeDetailsCodec.java
similarity index 52%
copy from hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconDBDefinition.java
copy to hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/codec/DatanodeDetailsCodec.java
index bcfe060..c11ebbf 100644
--- a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconDBDefinition.java
+++ b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/codec/DatanodeDetailsCodec.java
@@ -16,23 +16,34 @@
  * limitations under the License.
  *
  */
-package org.apache.hadoop.ozone.recon.scm;
 
-import org.apache.hadoop.hdds.scm.metadata.SCMDBDefinition;
-import org.apache.hadoop.ozone.recon.ReconServerConfigKeys;
+package org.apache.hadoop.ozone.recon.codec;
+
+import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.DatanodeDetailsProto.PARSER;
+
+import java.io.IOException;
+
+import org.apache.hadoop.hdds.protocol.DatanodeDetails;
+import org.apache.hadoop.hdds.utils.db.Codec;
 
 /**
- * SCM db file for ozone.
+ * Codec for DatanodeDetails.
  */
-public class ReconDBDefinition extends SCMDBDefinition {
+public class DatanodeDetailsCodec implements Codec<DatanodeDetails> {
+
+  @Override
+  public byte[] toPersistedFormat(DatanodeDetails object) throws IOException {
+    return object.getProtoBufMessage().toByteArray();
+  }
 
   @Override
-  public String getName() {
-    return "recon-scm.db";
+  public DatanodeDetails fromPersistedFormat(byte[] rawData)
+      throws IOException {
+    return DatanodeDetails.getFromProtoBuf(PARSER.parseFrom(rawData));
   }
 
   @Override
-  public String getLocationConfigKey() {
-    return ReconServerConfigKeys.OZONE_RECON_SCM_DB_DIR;
+  public DatanodeDetails copyObject(DatanodeDetails object) {
+    return object;
   }
 }
diff --git a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconDBDefinition.java b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/codec/ReconNodeDBKeyCodec.java
similarity index 59%
copy from hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconDBDefinition.java
copy to hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/codec/ReconNodeDBKeyCodec.java
index bcfe060..8c56920 100644
--- a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconDBDefinition.java
+++ b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/codec/ReconNodeDBKeyCodec.java
@@ -16,23 +16,31 @@
  * limitations under the License.
  *
  */
-package org.apache.hadoop.ozone.recon.scm;
 
-import org.apache.hadoop.hdds.scm.metadata.SCMDBDefinition;
-import org.apache.hadoop.ozone.recon.ReconServerConfigKeys;
+package org.apache.hadoop.ozone.recon.codec;
+
+import java.io.IOException;
+import java.util.UUID;
+
+import org.apache.hadoop.hdds.StringUtils;
+import org.apache.hadoop.hdds.utils.db.Codec;
 
 /**
- * SCM db file for ozone.
+ * Codec for UUID.
  */
-public class ReconDBDefinition extends SCMDBDefinition {
+public class ReconNodeDBKeyCodec implements Codec<UUID> {
+  @Override
+  public byte[] toPersistedFormat(UUID object) throws IOException {
+    return StringUtils.string2Bytes(object.toString());
+  }
 
   @Override
-  public String getName() {
-    return "recon-scm.db";
+  public UUID fromPersistedFormat(byte[] rawData) throws IOException {
+    return UUID.fromString(StringUtils.bytes2String(rawData));
   }
 
   @Override
-  public String getLocationConfigKey() {
-    return ReconServerConfigKeys.OZONE_RECON_SCM_DB_DIR;
+  public UUID copyObject(UUID object) {
+    return null;
   }
 }
diff --git a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconDBDefinition.java b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/codec/package-info.java
similarity index 55%
copy from hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconDBDefinition.java
copy to hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/codec/package-info.java
index bcfe060..0812d39 100644
--- a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconDBDefinition.java
+++ b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/codec/package-info.java
@@ -5,34 +5,18 @@
  * 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
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
+ * 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.recon.scm;
-
-import org.apache.hadoop.hdds.scm.metadata.SCMDBDefinition;
-import org.apache.hadoop.ozone.recon.ReconServerConfigKeys;
 
 /**
- * SCM db file for ozone.
+ * This package defines the codecs for Recon DB tables.
  */
-public class ReconDBDefinition extends SCMDBDefinition {
-
-  @Override
-  public String getName() {
-    return "recon-scm.db";
-  }
-
-  @Override
-  public String getLocationConfigKey() {
-    return ReconServerConfigKeys.OZONE_RECON_SCM_DB_DIR;
-  }
-}
+package org.apache.hadoop.ozone.recon.codec;
\ No newline at end of file
diff --git a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconNodeManager.java b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconNodeManager.java
index 60e8a06..d7a6104 100644
--- a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconNodeManager.java
+++ b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconNodeManager.java
@@ -18,7 +18,6 @@
 
 package org.apache.hadoop.ozone.recon.scm;
 
-import java.io.File;
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.List;
@@ -26,29 +25,21 @@ import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
 
-import org.apache.hadoop.hdds.StringUtils;
-import org.apache.hadoop.hdds.conf.ConfigurationSource;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.hdds.protocol.DatanodeDetails;
-import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
 import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.SCMCommandProto.Type;
 import org.apache.hadoop.hdds.scm.net.NetworkTopology;
 import org.apache.hadoop.hdds.scm.node.SCMNodeManager;
 import org.apache.hadoop.hdds.scm.server.SCMStorageConfig;
 import org.apache.hadoop.hdds.server.events.EventPublisher;
-import org.apache.hadoop.hdds.utils.MetadataStore;
-import org.apache.hadoop.hdds.utils.MetadataStoreBuilder;
-import org.apache.hadoop.ozone.OzoneConsts;
+import org.apache.hadoop.hdds.utils.db.Table;
+import org.apache.hadoop.hdds.utils.db.TableIterator;
 import org.apache.hadoop.ozone.protocol.commands.CommandForDatanode;
 import org.apache.hadoop.ozone.protocol.commands.SCMCommand;
-import org.apache.hadoop.ozone.recon.ReconUtils;
 import org.apache.hadoop.util.Time;
 
 import com.google.common.collect.ImmutableSet;
 import static org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.SCMCommandProto.Type.reregisterCommand;
-import static org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_DB_CACHE_SIZE_DEFAULT;
-import static org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_DB_CACHE_SIZE_MB;
-import static org.apache.hadoop.ozone.recon.ReconConstants.RECON_SCM_NODE_DB;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -60,7 +51,7 @@ public class ReconNodeManager extends SCMNodeManager {
   public static final Logger LOG = LoggerFactory
       .getLogger(ReconNodeManager.class);
 
-  private final MetadataStore nodeStore;
+  private Table<UUID, DatanodeDetails> nodeDB;
   private final static Set<Type> ALLOWED_COMMANDS =
       ImmutableSet.of(reregisterCommand);
 
@@ -73,27 +64,20 @@ public class ReconNodeManager extends SCMNodeManager {
   public ReconNodeManager(OzoneConfiguration conf,
                           SCMStorageConfig scmStorageConfig,
                           EventPublisher eventPublisher,
-                          NetworkTopology networkTopology) throws IOException {
+                          NetworkTopology networkTopology,
+                          Table<UUID, DatanodeDetails> nodeDB) {
     super(conf, scmStorageConfig, eventPublisher, networkTopology);
-    final File nodeDBPath = getNodeDBPath(conf);
-    final int cacheSize = conf.getInt(OZONE_SCM_DB_CACHE_SIZE_MB,
-        OZONE_SCM_DB_CACHE_SIZE_DEFAULT);
-    this.nodeStore = MetadataStoreBuilder.newBuilder()
-        .setConf(conf)
-        .setDbFile(nodeDBPath)
-        .setCacheSize(cacheSize * OzoneConsts.MB)
-        .build();
+    this.nodeDB = nodeDB;
     loadExistingNodes();
   }
 
   private void loadExistingNodes() {
     try {
-      List<Map.Entry<byte[], byte[]>> range = nodeStore
-          .getSequentialRangeKVs(null, Integer.MAX_VALUE, null);
       int nodeCount = 0;
-      for (Map.Entry<byte[], byte[]> entry : range) {
-        DatanodeDetails datanodeDetails = DatanodeDetails.getFromProtoBuf(
-            HddsProtos.DatanodeDetailsProto.PARSER.parseFrom(entry.getValue()));
+      TableIterator<UUID, ? extends Table.KeyValue<UUID, DatanodeDetails>>
+          iterator = nodeDB.iterator();
+      while (iterator.hasNext()) {
+        DatanodeDetails datanodeDetails = iterator.next().getValue();
         register(datanodeDetails, null, null);
         nodeCount++;
       }
@@ -108,27 +92,10 @@ public class ReconNodeManager extends SCMNodeManager {
    * @param datanodeDetails Datanode details.
    */
   public void addNodeToDB(DatanodeDetails datanodeDetails) throws IOException {
-    byte[] nodeIdBytes =
-        StringUtils.string2Bytes(datanodeDetails.getUuidString());
-    byte[] nodeDetailsBytes =
-        datanodeDetails.getProtoBufMessage().toByteArray();
-    nodeStore.put(nodeIdBytes, nodeDetailsBytes);
+    nodeDB.put(datanodeDetails.getUuid(), datanodeDetails);
     LOG.info("Adding new node {} to Node DB.", datanodeDetails.getUuid());
   }
 
-  protected File getNodeDBPath(ConfigurationSource conf) {
-    File metaDir = ReconUtils.getReconScmDbDir(conf);
-    return new File(metaDir, RECON_SCM_NODE_DB);
-  }
-
-  @Override
-  public void close() throws IOException {
-    if (nodeStore != null) {
-      nodeStore.close();
-    }
-    super.close();
-  }
-
   /**
    * Returns the last heartbeat time of the given node.
    *
diff --git a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconDBDefinition.java b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconSCMDBDefinition.java
similarity index 55%
rename from hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconDBDefinition.java
rename to hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconSCMDBDefinition.java
index bcfe060..e56a66b 100644
--- a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconDBDefinition.java
+++ b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconSCMDBDefinition.java
@@ -18,21 +18,44 @@
  */
 package org.apache.hadoop.ozone.recon.scm;
 
+import java.util.UUID;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.hadoop.hdds.protocol.DatanodeDetails;
 import org.apache.hadoop.hdds.scm.metadata.SCMDBDefinition;
+import org.apache.hadoop.hdds.utils.db.DBColumnFamilyDefinition;
 import org.apache.hadoop.ozone.recon.ReconServerConfigKeys;
+import org.apache.hadoop.ozone.recon.codec.DatanodeDetailsCodec;
+import org.apache.hadoop.ozone.recon.codec.ReconNodeDBKeyCodec;
 
 /**
- * SCM db file for ozone.
+ * Recon SCM db file for ozone.
  */
-public class ReconDBDefinition extends SCMDBDefinition {
+public class ReconSCMDBDefinition extends SCMDBDefinition {
+
+  public static final String RECON_SCM_DB_NAME = "recon-scm.db";
+
+  public static final DBColumnFamilyDefinition<UUID, DatanodeDetails>
+      NODES =
+      new DBColumnFamilyDefinition<UUID, DatanodeDetails>(
+          "nodes",
+          UUID.class,
+          new ReconNodeDBKeyCodec(),
+          DatanodeDetails.class,
+          new DatanodeDetailsCodec());
 
   @Override
   public String getName() {
-    return "recon-scm.db";
+    return RECON_SCM_DB_NAME;
   }
 
   @Override
   public String getLocationConfigKey() {
     return ReconServerConfigKeys.OZONE_RECON_SCM_DB_DIR;
   }
+
+  @Override
+  public DBColumnFamilyDefinition[] getColumnFamilies() {
+    return ArrayUtils.add(super.getColumnFamilies(), NODES);
+  }
 }
diff --git a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconStorageContainerManagerFacade.java b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconStorageContainerManagerFacade.java
index 34a930a..3a0342e 100644
--- a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconStorageContainerManagerFacade.java
+++ b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/scm/ReconStorageContainerManagerFacade.java
@@ -100,10 +100,11 @@ public class ReconStorageContainerManagerFacade
     this.scmStorageConfig = new ReconStorageConfig(conf);
     this.clusterMap = new NetworkTopologyImpl(conf);
     dbStore = DBStoreBuilder
-        .createDBStore(ozoneConfiguration, new ReconDBDefinition());
+        .createDBStore(ozoneConfiguration, new ReconSCMDBDefinition());
 
     this.nodeManager =
-        new ReconNodeManager(conf, scmStorageConfig, eventQueue, clusterMap);
+        new ReconNodeManager(conf, scmStorageConfig, eventQueue, clusterMap,
+            ReconSCMDBDefinition.NODES.getTable(dbStore));
     placementMetrics = SCMContainerPlacementMetrics.create();
     this.containerPlacementPolicy =
         ContainerPlacementPolicyFactory.getPolicy(conf, nodeManager,
@@ -114,10 +115,10 @@ public class ReconStorageContainerManagerFacade
 
         new ReconPipelineManager(conf,
             nodeManager,
-            ReconDBDefinition.PIPELINES.getTable(dbStore),
+            ReconSCMDBDefinition.PIPELINES.getTable(dbStore),
             eventQueue);
     this.containerManager = new ReconContainerManager(conf,
-        ReconDBDefinition.CONTAINERS.getTable(dbStore),
+        ReconSCMDBDefinition.CONTAINERS.getTable(dbStore),
         dbStore,
         pipelineManager,
         scmServiceProvider,
diff --git a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/spi/impl/ContainerDBServiceProviderImpl.java b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/spi/impl/ContainerDBServiceProviderImpl.java
index ec87352..aeefeef 100644
--- a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/spi/impl/ContainerDBServiceProviderImpl.java
+++ b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/spi/impl/ContainerDBServiceProviderImpl.java
@@ -19,9 +19,9 @@
 package org.apache.hadoop.ozone.recon.spi.impl;
 
 import static org.apache.hadoop.ozone.recon.ReconConstants.CONTAINER_COUNT_KEY;
-import static org.apache.hadoop.ozone.recon.ReconConstants.CONTAINER_KEY_COUNT_TABLE;
-import static org.apache.hadoop.ozone.recon.ReconConstants.CONTAINER_KEY_TABLE;
 import static org.apache.hadoop.ozone.recon.spi.impl.ReconContainerDBProvider.getNewDBStore;
+import static org.apache.hadoop.ozone.recon.spi.impl.ReconDBDefinition.CONTAINER_KEY;
+import static org.apache.hadoop.ozone.recon.spi.impl.ReconDBDefinition.CONTAINER_KEY_COUNT;
 import static org.jooq.impl.DSL.currentTimestamp;
 import static org.jooq.impl.DSL.select;
 import static org.jooq.impl.DSL.using;
@@ -38,10 +38,8 @@ import javax.inject.Singleton;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
-import org.apache.hadoop.ozone.recon.ReconUtils;
 import org.apache.hadoop.ozone.recon.api.types.ContainerKeyPrefix;
 import org.apache.hadoop.ozone.recon.api.types.ContainerMetadata;
-import org.apache.hadoop.ozone.recon.persistence.ContainerSchemaManager;
 import org.apache.hadoop.ozone.recon.spi.ContainerDBServiceProvider;
 import org.apache.hadoop.hdds.utils.db.DBStore;
 import org.apache.hadoop.hdds.utils.db.Table;
@@ -68,9 +66,6 @@ public class ContainerDBServiceProviderImpl
   private GlobalStatsDao globalStatsDao;
 
   @Inject
-  private ContainerSchemaManager containerSchemaManager;
-
-  @Inject
   private OzoneConfiguration configuration;
 
   @Inject
@@ -80,9 +75,6 @@ public class ContainerDBServiceProviderImpl
   private Configuration sqlConfiguration;
 
   @Inject
-  private ReconUtils reconUtils;
-
-  @Inject
   public ContainerDBServiceProviderImpl(DBStore dbStore,
                                         Configuration sqlConfiguration) {
     containerDbStore = dbStore;
@@ -113,13 +105,19 @@ public class ContainerDBServiceProviderImpl
       throws IOException {
 
     File oldDBLocation = containerDbStore.getDbLocation();
-    containerDbStore = getNewDBStore(configuration, reconUtils);
+    try {
+      containerDbStore.close();
+    } catch (Exception e) {
+      LOG.warn("Unable to close old Recon container key DB at {}.",
+          containerDbStore.getDbLocation().getAbsolutePath());
+    }
+    containerDbStore = getNewDBStore(configuration);
     LOG.info("Creating new Recon Container DB at {}",
         containerDbStore.getDbLocation().getAbsolutePath());
     initializeTables();
 
     if (oldDBLocation.exists()) {
-      LOG.info("Cleaning up old Recon Container DB at {}.",
+      LOG.info("Cleaning up old Recon Container key DB at {}.",
           oldDBLocation.getAbsolutePath());
       FileUtils.deleteDirectory(oldDBLocation);
     }
@@ -140,10 +138,9 @@ public class ContainerDBServiceProviderImpl
    */
   private void initializeTables() {
     try {
-      this.containerKeyTable = containerDbStore.getTable(CONTAINER_KEY_TABLE,
-          ContainerKeyPrefix.class, Integer.class);
-      this.containerKeyCountTable = containerDbStore
-          .getTable(CONTAINER_KEY_COUNT_TABLE, Long.class, Long.class);
+      this.containerKeyTable = CONTAINER_KEY.getTable(containerDbStore);
+      this.containerKeyCountTable =
+          CONTAINER_KEY_COUNT.getTable(containerDbStore);
     } catch (IOException e) {
       LOG.error("Unable to create Container Key tables.", e);
     }
diff --git a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/spi/impl/ReconContainerDBProvider.java b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/spi/impl/ReconContainerDBProvider.java
index d622eb3..ec36597 100644
--- a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/spi/impl/ReconContainerDBProvider.java
+++ b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/spi/impl/ReconContainerDBProvider.java
@@ -18,20 +18,15 @@
 
 package org.apache.hadoop.ozone.recon.spi.impl;
 
-import static org.apache.hadoop.ozone.recon.ReconConstants.CONTAINER_KEY_COUNT_TABLE;
 import static org.apache.hadoop.ozone.recon.ReconConstants.RECON_CONTAINER_KEY_DB;
-import static org.apache.hadoop.ozone.recon.ReconConstants.CONTAINER_KEY_TABLE;
 import static org.apache.hadoop.ozone.recon.ReconServerConfigKeys.OZONE_RECON_DB_DIR;
 
 import java.io.File;
-import java.nio.file.Path;
 
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.ozone.recon.ReconUtils;
-import org.apache.hadoop.ozone.recon.api.types.ContainerKeyPrefix;
 import org.apache.hadoop.hdds.utils.db.DBStore;
 import org.apache.hadoop.hdds.utils.db.DBStoreBuilder;
-import org.apache.hadoop.hdds.utils.db.IntegerCodec;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -69,10 +64,10 @@ public class ReconContainerDBProvider implements Provider<DBStore> {
     if (lastKnownContainerKeyDb != null) {
       LOG.info("Last known container-key DB : {}",
           lastKnownContainerKeyDb.getAbsolutePath());
-      dbStore = initializeDBStore(configuration, reconUtils,
+      dbStore = initializeDBStore(configuration,
           lastKnownContainerKeyDb.getName());
     } else {
-      dbStore = getNewDBStore(configuration, reconUtils);
+      dbStore = getNewDBStore(configuration);
     }
     if (dbStore == null) {
       throw new ProvisionException("Unable to provide instance of DBStore " +
@@ -82,28 +77,19 @@ public class ReconContainerDBProvider implements Provider<DBStore> {
   }
 
   private static DBStore initializeDBStore(OzoneConfiguration configuration,
-      ReconUtils reconUtils, String dbName) {
+                                           String dbName) {
     DBStore dbStore = null;
     try {
-      Path metaDir = reconUtils.getReconDbDir(
-          configuration, OZONE_RECON_DB_DIR).toPath();
-      dbStore = DBStoreBuilder.newBuilder(configuration)
-          .setPath(metaDir)
-          .setName(dbName)
-          .addTable(CONTAINER_KEY_TABLE)
-          .addTable(CONTAINER_KEY_COUNT_TABLE)
-          .addCodec(ContainerKeyPrefix.class, new ContainerKeyPrefixCodec())
-          .addCodec(Integer.class, new IntegerCodec())
-          .build();
+      dbStore = DBStoreBuilder.createDBStore(configuration,
+          new ReconDBDefinition(dbName));
     } catch (Exception ex) {
       LOG.error("Unable to initialize Recon container metadata store.", ex);
     }
     return dbStore;
   }
 
-  static DBStore getNewDBStore(OzoneConfiguration configuration,
-                               ReconUtils reconUtils) {
+  static DBStore getNewDBStore(OzoneConfiguration configuration) {
     String dbName = RECON_CONTAINER_KEY_DB + "_" + System.currentTimeMillis();
-    return initializeDBStore(configuration, reconUtils, dbName);
+    return initializeDBStore(configuration, dbName);
   }
 }
diff --git a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/spi/impl/ReconDBDefinition.java b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/spi/impl/ReconDBDefinition.java
new file mode 100644
index 0000000..4f5a4c7
--- /dev/null
+++ b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/spi/impl/ReconDBDefinition.java
@@ -0,0 +1,71 @@
+/*
+ * 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
+ *
+ *      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.recon.spi.impl;
+
+import org.apache.hadoop.hdds.utils.db.DBColumnFamilyDefinition;
+import org.apache.hadoop.hdds.utils.db.DBDefinition;
+import org.apache.hadoop.hdds.utils.db.IntegerCodec;
+import org.apache.hadoop.hdds.utils.db.LongCodec;
+import org.apache.hadoop.ozone.recon.ReconServerConfigKeys;
+import org.apache.hadoop.ozone.recon.api.types.ContainerKeyPrefix;
+
+/**
+ * RocksDB definition for the DB internal to Recon.
+ */
+public class ReconDBDefinition implements DBDefinition {
+
+  private String dbName;
+
+  public ReconDBDefinition(String dbName) {
+    this.dbName = dbName;
+  }
+
+  public static final DBColumnFamilyDefinition<ContainerKeyPrefix, Integer>
+      CONTAINER_KEY =
+      new DBColumnFamilyDefinition<>(
+          "containerKeyTable",
+          ContainerKeyPrefix.class,
+          new ContainerKeyPrefixCodec(),
+          Integer.class,
+          new IntegerCodec());
+
+  public static final DBColumnFamilyDefinition<Long, Long>
+      CONTAINER_KEY_COUNT =
+      new DBColumnFamilyDefinition<>(
+          "containerKeyCountTable",
+          Long.class,
+          new LongCodec(),
+          Long.class,
+          new LongCodec());
+
+  @Override
+  public String getName() {
+    return dbName;
+  }
+
+  @Override
+  public String getLocationConfigKey() {
+    return ReconServerConfigKeys.OZONE_RECON_DB_DIR;
+  }
+
+  @Override
+  public DBColumnFamilyDefinition[] getColumnFamilies() {
+    return new DBColumnFamilyDefinition[] {CONTAINER_KEY, CONTAINER_KEY_COUNT};
+  }
+}
diff --git a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/scm/AbstractReconContainerManagerTest.java b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/scm/AbstractReconContainerManagerTest.java
index 04010e5..3114c02 100644
--- a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/scm/AbstractReconContainerManagerTest.java
+++ b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/scm/AbstractReconContainerManagerTest.java
@@ -69,17 +69,17 @@ public class AbstractReconContainerManagerTest {
     conf.set(OZONE_METADATA_DIRS,
         temporaryFolder.newFolder().getAbsolutePath());
     conf.set(OZONE_SCM_NAMES, "localhost");
-    store = DBStoreBuilder.createDBStore(conf, new ReconDBDefinition());
+    store = DBStoreBuilder.createDBStore(conf, new ReconSCMDBDefinition());
     scmStorageConfig = new ReconStorageConfig(conf);
     NetworkTopology clusterMap = new NetworkTopologyImpl(conf);
     EventQueue eventQueue = new EventQueue();
     NodeManager nodeManager =
         new SCMNodeManager(conf, scmStorageConfig, eventQueue, clusterMap);
     pipelineManager = new ReconPipelineManager(conf, nodeManager,
-        ReconDBDefinition.PIPELINES.getTable(store), eventQueue);
+        ReconSCMDBDefinition.PIPELINES.getTable(store), eventQueue);
     containerManager = new ReconContainerManager(
         conf,
-        ReconDBDefinition.CONTAINERS.getTable(store),
+        ReconSCMDBDefinition.CONTAINERS.getTable(store),
         store,
         pipelineManager,
         getScmServiceProvider(),
diff --git a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/scm/TestReconNodeManager.java b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/scm/TestReconNodeManager.java
index 19290b1..c934cae 100644
--- a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/scm/TestReconNodeManager.java
+++ b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/scm/TestReconNodeManager.java
@@ -26,12 +26,17 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
+import java.util.UUID;
 
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.hdds.protocol.DatanodeDetails;
 import org.apache.hadoop.hdds.scm.net.NetworkTopology;
 import org.apache.hadoop.hdds.scm.net.NetworkTopologyImpl;
 import org.apache.hadoop.hdds.server.events.EventQueue;
+import org.apache.hadoop.hdds.utils.db.DBStore;
+import org.apache.hadoop.hdds.utils.db.DBStoreBuilder;
+import org.apache.hadoop.hdds.utils.db.Table;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -46,6 +51,7 @@ public class TestReconNodeManager {
   public TemporaryFolder temporaryFolder = new TemporaryFolder();
 
   private OzoneConfiguration conf;
+  private DBStore store;
 
   @Before
   public void setUp() throws Exception {
@@ -53,6 +59,12 @@ public class TestReconNodeManager {
     conf.set(OZONE_METADATA_DIRS,
         temporaryFolder.newFolder().getAbsolutePath());
     conf.set(OZONE_SCM_NAMES, "localhost");
+    store = DBStoreBuilder.createDBStore(conf, new ReconSCMDBDefinition());
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    store.close();
   }
 
   @Test
@@ -60,8 +72,10 @@ public class TestReconNodeManager {
     ReconStorageConfig scmStorageConfig = new ReconStorageConfig(conf);
     EventQueue eventQueue = new EventQueue();
     NetworkTopology clusterMap = new NetworkTopologyImpl(conf);
+    Table<UUID, DatanodeDetails> nodeTable =
+        ReconSCMDBDefinition.NODES.getTable(store);
     ReconNodeManager reconNodeManager = new ReconNodeManager(conf,
-        scmStorageConfig, eventQueue, clusterMap);
+        scmStorageConfig, eventQueue, clusterMap, nodeTable);
     ReconNewNodeHandler reconNewNodeHandler =
         new ReconNewNodeHandler(reconNodeManager);
     assertTrue(reconNodeManager.getAllNodes().isEmpty());
@@ -80,8 +94,8 @@ public class TestReconNodeManager {
     // Close the DB, and recreate the instance of Recon Node Manager.
     eventQueue.close();
     reconNodeManager.close();
-    reconNodeManager = new ReconNodeManager(conf,
-        scmStorageConfig, eventQueue, clusterMap);
+    reconNodeManager = new ReconNodeManager(conf, scmStorageConfig, eventQueue,
+        clusterMap, nodeTable);
 
     // Verify that the node information was persisted and loaded back.
     assertEquals(1, reconNodeManager.getAllNodes().size());
diff --git a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/scm/TestReconPipelineManager.java b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/scm/TestReconPipelineManager.java
index c891f33..b190810 100644
--- a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/scm/TestReconPipelineManager.java
+++ b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/scm/TestReconPipelineManager.java
@@ -73,7 +73,7 @@ public class TestReconPipelineManager {
         temporaryFolder.newFolder().getAbsolutePath());
     conf.set(OZONE_SCM_NAMES, "localhost");
     scmStorageConfig = new ReconStorageConfig(conf);
-    store = DBStoreBuilder.createDBStore(conf, new ReconDBDefinition());
+    store = DBStoreBuilder.createDBStore(conf, new ReconSCMDBDefinition());
   }
 
   @After
@@ -114,7 +114,7 @@ public class TestReconPipelineManager {
 
     try (ReconPipelineManager reconPipelineManager =
         new ReconPipelineManager(conf, nodeManager,
-            ReconDBDefinition.PIPELINES.getTable(store), eventQueue)) {
+            ReconSCMDBDefinition.PIPELINES.getTable(store), eventQueue)) {
       reconPipelineManager.addPipeline(validPipeline);
       reconPipelineManager.addPipeline(invalidPipeline);
 
@@ -150,7 +150,7 @@ public class TestReconPipelineManager {
 
     ReconPipelineManager reconPipelineManager =
         new ReconPipelineManager(conf, nodeManager,
-            ReconDBDefinition.PIPELINES.getTable(store), eventQueue);
+            ReconSCMDBDefinition.PIPELINES.getTable(store), eventQueue);
     assertFalse(reconPipelineManager.containsPipeline(pipeline.getId()));
     reconPipelineManager.addPipeline(pipeline);
     assertTrue(reconPipelineManager.containsPipeline(pipeline.getId()));
@@ -162,7 +162,7 @@ public class TestReconPipelineManager {
     NodeManager nodeManagerMock = mock(NodeManager.class);
 
     ReconPipelineManager reconPipelineManager = new ReconPipelineManager(
-        conf, nodeManagerMock, ReconDBDefinition.PIPELINES.getTable(store),
+        conf, nodeManagerMock, ReconSCMDBDefinition.PIPELINES.getTable(store),
         new EventQueue());
     PipelineFactory pipelineFactory = reconPipelineManager.getPipelineFactory();
     assertTrue(pipelineFactory instanceof ReconPipelineFactory);
diff --git a/hadoop-ozone/tools/pom.xml b/hadoop-ozone/tools/pom.xml
index 7fb0833..36f861c 100644
--- a/hadoop-ozone/tools/pom.xml
+++ b/hadoop-ozone/tools/pom.xml
@@ -65,6 +65,10 @@ https://maven.apache.org/xsd/maven-4.0.0.xsd">
     </dependency>
     <dependency>
       <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-ozone-recon</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
       <artifactId>hadoop-hdfs</artifactId>
     </dependency>
     <dependency>
diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/DBDefinitionFactory.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/DBDefinitionFactory.java
index 3f28a64..d9d0d70 100644
--- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/DBDefinitionFactory.java
+++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/DBDefinitionFactory.java
@@ -18,10 +18,16 @@
 
 package org.apache.hadoop.ozone.debug;
 
+import static org.apache.hadoop.ozone.recon.ReconConstants.RECON_CONTAINER_KEY_DB;
+import static org.apache.hadoop.ozone.recon.ReconConstants.RECON_OM_SNAPSHOT_DB;
+
 import org.apache.hadoop.hdds.scm.metadata.SCMDBDefinition;
 import org.apache.hadoop.hdds.utils.db.DBDefinition;
 import org.apache.hadoop.ozone.om.codec.OMDBDefinition;
+import org.apache.hadoop.ozone.recon.scm.ReconSCMDBDefinition;
+import org.apache.hadoop.ozone.recon.spi.impl.ReconDBDefinition;
 
+import java.util.Arrays;
 import java.util.HashMap;
 
 /**
@@ -36,14 +42,26 @@ public final class DBDefinitionFactory {
 
   static {
     dbMap = new HashMap<>();
-    dbMap.put(new SCMDBDefinition().getName(), new SCMDBDefinition());
-    dbMap.put(new OMDBDefinition().getName(), new OMDBDefinition());
+    Arrays.asList(
+      new SCMDBDefinition(),
+      new OMDBDefinition(),
+      new ReconSCMDBDefinition()
+    ).forEach(dbDefinition -> dbMap.put(dbDefinition.getName(), dbDefinition));
   }
 
   public static DBDefinition getDefinition(String dbName){
     if (dbMap.containsKey(dbName)){
       return dbMap.get(dbName);
     }
+    return getReconDBDefinition(dbName);
+  }
+
+  private static DBDefinition getReconDBDefinition(String dbName){
+    if (dbName.startsWith(RECON_CONTAINER_KEY_DB)) {
+      return new ReconDBDefinition(dbName);
+    } else if (dbName.startsWith(RECON_OM_SNAPSHOT_DB)) {
+      return new OMDBDefinition();
+    }
     return null;
   }
 }
diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/DBScanner.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/DBScanner.java
index 47fc8bc..5da64e0 100644
--- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/DBScanner.java
+++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/DBScanner.java
@@ -44,6 +44,12 @@ public class DBScanner implements Callable<Void> {
             description = "Table name")
   private String tableName;
 
+  @CommandLine.Option(names = {"--with-keys"},
+      description = "List Key -> Value instead of just Value.",
+      defaultValue = "false",
+      showDefaultValue = CommandLine.Help.Visibility.ALWAYS)
+  private boolean withKey;
+
   @CommandLine.ParentCommand
   private RDBParser parent;
 
@@ -51,21 +57,29 @@ public class DBScanner implements Callable<Void> {
 
   private static void displayTable(RocksDB rocksDB,
         DBColumnFamilyDefinition dbColumnFamilyDefinition,
-        List<ColumnFamilyHandle> list) throws IOException {
+        List<ColumnFamilyHandle> list, boolean withKey) throws IOException {
     ColumnFamilyHandle columnFamilyHandle = getColumnFamilyHandle(
             dbColumnFamilyDefinition.getTableName()
                     .getBytes(StandardCharsets.UTF_8), list);
-    if (columnFamilyHandle==null){
+    if (columnFamilyHandle == null) {
       throw new IllegalArgumentException("columnFamilyHandle is null");
     }
     RocksIterator iterator = rocksDB.newIterator(columnFamilyHandle);
     iterator.seekToFirst();
     while (iterator.isValid()){
+      StringBuilder result = new StringBuilder();
+      if (withKey) {
+        Object key = dbColumnFamilyDefinition.getKeyCodec()
+            .fromPersistedFormat(iterator.key());
+        Gson gson = new GsonBuilder().setPrettyPrinting().create();
+        result.append(gson.toJson(key));
+        result.append(" -> ");
+      }
       Object o = dbColumnFamilyDefinition.getValueCodec()
               .fromPersistedFormat(iterator.value());
       Gson gson = new GsonBuilder().setPrettyPrinting().create();
-      String result = gson.toJson(o);
-      System.out.println(result);
+      result.append(gson.toJson(o));
+      System.out.println(result.toString());
       iterator.next();
     }
   }
@@ -132,7 +146,8 @@ public class DBScanner implements Callable<Void> {
       } else {
         DBColumnFamilyDefinition columnFamilyDefinition =
                 this.columnFamilyMap.get(tableName);
-        displayTable(rocksDB, columnFamilyDefinition, columnFamilyHandleList);
+        displayTable(rocksDB, columnFamilyDefinition, columnFamilyHandleList,
+            withKey);
       }
     } else {
       System.out.println("Incorrect db Path");
diff --git a/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/debug/TestDBDefinitionFactory.java b/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/debug/TestDBDefinitionFactory.java
new file mode 100644
index 0000000..f63d149
--- /dev/null
+++ b/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/debug/TestDBDefinitionFactory.java
@@ -0,0 +1,59 @@
+/*
+ * 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.debug;
+
+import static org.apache.hadoop.ozone.recon.ReconConstants.RECON_CONTAINER_KEY_DB;
+import static org.apache.hadoop.ozone.recon.ReconConstants.RECON_OM_SNAPSHOT_DB;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.hadoop.hdds.scm.metadata.SCMDBDefinition;
+import org.apache.hadoop.hdds.utils.db.DBDefinition;
+import org.apache.hadoop.ozone.om.codec.OMDBDefinition;
+import org.apache.hadoop.ozone.recon.scm.ReconSCMDBDefinition;
+import org.apache.hadoop.ozone.recon.spi.impl.ReconDBDefinition;
+import org.junit.Test;
+
+/**
+ * Simple factory unit test.
+ */
+public class TestDBDefinitionFactory {
+
+  @Test
+  public void testGetDefinition() {
+    DBDefinition definition =
+        DBDefinitionFactory.getDefinition(new OMDBDefinition().getName());
+    assertTrue(definition instanceof OMDBDefinition);
+
+    definition = DBDefinitionFactory.getDefinition(
+        new SCMDBDefinition().getName());
+    assertTrue(definition instanceof SCMDBDefinition);
+
+    definition = DBDefinitionFactory.getDefinition(
+        new ReconSCMDBDefinition().getName());
+    assertTrue(definition instanceof ReconSCMDBDefinition);
+
+    definition = DBDefinitionFactory.getDefinition(
+        RECON_OM_SNAPSHOT_DB + "_1");
+    assertTrue(definition instanceof OMDBDefinition);
+
+    definition = DBDefinitionFactory.getDefinition(
+        RECON_CONTAINER_KEY_DB + "_1");
+    assertTrue(definition instanceof ReconDBDefinition);
+  }
+}
\ No newline at end of file


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