Skip to content

Commit 24793d2

Browse files
committed
HDDS-1163. Basic framework for Ozone Data Scrubber. Contributed by Supratim Deka.
1 parent ab574ff commit 24793d2

File tree

8 files changed

+904
-3
lines changed

8 files changed

+904
-3
lines changed

hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/HddsConfigKeys.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ public final class HddsConfigKeys {
6565
public static final float HDDS_CONTAINER_CLOSE_THRESHOLD_DEFAULT = 0.9f;
6666
public static final String HDDS_SCM_CHILLMODE_ENABLED =
6767
"hdds.scm.chillmode.enabled";
68+
public static final String HDDS_CONTAINERSCRUB_ENABLED =
69+
"hdds.containerscrub.enabled";
70+
public static final boolean HDDS_CONTAINERSCRUB_ENABLED_DEFAULT = false;
6871
public static final boolean HDDS_SCM_CHILLMODE_ENABLED_DEFAULT = true;
6972
public static final String HDDS_SCM_CHILLMODE_MIN_DATANODE =
7073
"hdds.scm.chillmode.min.datanode";
@@ -255,4 +258,4 @@ private HddsConfigKeys() {
255258
public static final String
256259
HDDS_DATANODE_HTTP_KERBEROS_KEYTAB_FILE_KEY =
257260
"hdds.datanode.http.kerberos.keytab";
258-
}
261+
}

hadoop-hdds/common/src/main/resources/ozone-default.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,6 +1346,16 @@
13461346
</description>
13471347
</property>
13481348

1349+
<property>
1350+
<name>hdds.containerscrub.enabled</name>
1351+
<value>false</value>
1352+
<tag>DATANODE</tag>
1353+
<description>
1354+
Boolean value to enable data and metadata scrubbing in the containers
1355+
running on each datanode.
1356+
</description>
1357+
</property>
1358+
13491359
<property>
13501360
<name>hdds.container.action.max.limit</name>
13511361
<value>20</value>

hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/interfaces/Container.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,4 +151,9 @@ ContainerReplicaProto getContainerReport()
151151
* updates the blockCommitSequenceId.
152152
*/
153153
void updateBlockCommitSequenceId(long blockCommitSequenceId);
154+
155+
/**
156+
* check and report the structural integrity of the container.
157+
*/
158+
void check() throws StorageContainerException;
154159
}

hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueContainer.java

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -565,8 +565,13 @@ public void writeLockInterruptibly() throws InterruptedException {
565565
*/
566566
@Override
567567
public File getContainerFile() {
568-
return new File(containerData.getMetadataPath(), containerData
569-
.getContainerID() + OzoneConsts.CONTAINER_EXTENSION);
568+
return getContainerFile(containerData.getMetadataPath(),
569+
containerData.getContainerID());
570+
}
571+
572+
static File getContainerFile(String metadataPath, long containerId) {
573+
return new File(metadataPath,
574+
containerId + OzoneConsts.CONTAINER_EXTENSION);
570575
}
571576

572577
@Override
@@ -634,6 +639,66 @@ public File getContainerDBFile() {
634639
.getContainerID() + OzoneConsts.DN_CONTAINER_DB);
635640
}
636641

642+
/**
643+
* run integrity checks on the Container metadata.
644+
*/
645+
public void check() throws StorageContainerException {
646+
ContainerCheckLevel level = ContainerCheckLevel.NO_CHECK;
647+
long containerId = containerData.getContainerID();
648+
649+
switch (containerData.getState()) {
650+
case OPEN:
651+
level = ContainerCheckLevel.FAST_CHECK;
652+
LOG.info("Doing Fast integrity checks for Container ID : {},"
653+
+ " because it is OPEN", containerId);
654+
break;
655+
case CLOSING:
656+
level = ContainerCheckLevel.FAST_CHECK;
657+
LOG.info("Doing Fast integrity checks for Container ID : {},"
658+
+ " because it is CLOSING", containerId);
659+
break;
660+
case CLOSED:
661+
case QUASI_CLOSED:
662+
level = ContainerCheckLevel.FULL_CHECK;
663+
LOG.debug("Doing Full integrity checks for Container ID : {},"
664+
+ " because it is in {} state", containerId,
665+
containerData.getState());
666+
break;
667+
default:
668+
throw new StorageContainerException(
669+
"Invalid Container state found for Container : " + containerData
670+
.getContainerID(), INVALID_CONTAINER_STATE);
671+
}
672+
673+
if (level == ContainerCheckLevel.NO_CHECK) {
674+
LOG.debug("Skipping integrity checks for Container Id : {}", containerId);
675+
return;
676+
}
677+
678+
KeyValueContainerCheck checker =
679+
new KeyValueContainerCheck(containerData.getMetadataPath(), config,
680+
containerId, containerData);
681+
682+
switch (level) {
683+
case FAST_CHECK:
684+
checker.fastCheck();
685+
break;
686+
case FULL_CHECK:
687+
checker.fullCheck();
688+
break;
689+
case NO_CHECK:
690+
LOG.debug("Skipping integrity checks for Container Id : {}", containerId);
691+
break;
692+
default:
693+
// we should not be here at all, scuttle the ship!
694+
Preconditions.checkNotNull(0, "Invalid Containercheck level");
695+
}
696+
}
697+
698+
private enum ContainerCheckLevel {
699+
NO_CHECK, FAST_CHECK, FULL_CHECK
700+
}
701+
637702
/**
638703
* Creates a temporary file.
639704
* @param file

0 commit comments

Comments
 (0)