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 7e7c4363c9b HDDS-15371. [DiskBalancer] Use monotonic time for delayed
replica deletion (#10364)
7e7c4363c9b is described below
commit 7e7c4363c9b67ce3054d903f56fbc8065c786224
Author: slfan1989 <[email protected]>
AuthorDate: Wed May 27 13:09:14 2026 +0800
HDDS-15371. [DiskBalancer] Use monotonic time for delayed replica deletion
(#10364)
---
.../container/diskbalancer/DiskBalancerService.java | 17 +++++++++++++++--
.../diskbalancer/DiskBalancerServiceTestImpl.java | 8 ++++++++
.../container/diskbalancer/TestDiskBalancerTask.java | 12 ++++++------
3 files changed, 29 insertions(+), 8 deletions(-)
diff --git
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerService.java
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerService.java
index 53470ef0410..a33a2d665fb 100644
---
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerService.java
+++
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerService.java
@@ -31,6 +31,7 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
+import java.time.Clock;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -59,6 +60,7 @@
import org.apache.hadoop.hdds.utils.BackgroundTaskQueue;
import org.apache.hadoop.hdds.utils.BackgroundTaskResult;
import org.apache.hadoop.hdds.utils.FaultInjector;
+import org.apache.hadoop.hdds.utils.SlidingWindow;
import org.apache.hadoop.ozone.OzoneConsts;
import org.apache.hadoop.ozone.container.common.helpers.ContainerUtils;
import org.apache.hadoop.ozone.container.common.impl.ContainerData;
@@ -94,6 +96,7 @@ public class DiskBalancerService extends BackgroundService {
private OzoneContainer ozoneContainer;
private final ConfigurationSource conf;
+ private final Clock clock;
private double threshold;
private long bandwidthInMB;
@@ -135,10 +138,19 @@ public class DiskBalancerService extends
BackgroundService {
public DiskBalancerService(OzoneContainer ozoneContainer,
long serviceCheckInterval, long serviceCheckTimeout, TimeUnit timeUnit,
int workerSize, ConfigurationSource conf) throws IOException {
+ this(ozoneContainer, serviceCheckInterval, serviceCheckTimeout, timeUnit,
+ workerSize, conf, new SlidingWindow.MonotonicClock());
+ }
+
+ DiskBalancerService(OzoneContainer ozoneContainer,
+ long serviceCheckInterval, long serviceCheckTimeout, TimeUnit timeUnit,
+ int workerSize, ConfigurationSource conf, Clock clock)
+ throws IOException {
super("DiskBalancerService", serviceCheckInterval, timeUnit, workerSize,
serviceCheckTimeout);
this.ozoneContainer = ozoneContainer;
this.conf = conf;
+ this.clock = Objects.requireNonNull(clock, "clock");
String diskBalancerInfoPath = getDiskBalancerInfoPath();
Objects.requireNonNull(diskBalancerInfoPath);
@@ -634,7 +646,8 @@ public BackgroundTaskResult call() {
}
if (moveSucceeded && newContainer != null) {
// Add current old container to pendingDeletionContainers.
- pendingDeletionContainers.put(System.currentTimeMillis() +
replicaDeletionDelay, container);
+ pendingDeletionContainers.put(clock.millis() + replicaDeletionDelay,
+ container);
ContainerLogger.logMoveSuccess(newContainer.getContainerData(),
sourceVolume,
destVolume, containerSize, Time.monotonicNow() - startTime);
}
@@ -691,7 +704,7 @@ private void cleanupPendingDeletionContainers() {
private boolean tryCleanupOnePendingDeletionContainer() {
Map.Entry<Long, Container> entry =
pendingDeletionContainers.pollFirstEntry();
if (entry != null) {
- if (entry.getKey() <= System.currentTimeMillis()) {
+ if (entry.getKey() <= clock.millis()) {
// entry container is expired
deleteContainer(entry.getValue());
return true;
diff --git
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerServiceTestImpl.java
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerServiceTestImpl.java
index ef150321907..3f9bb384002 100644
---
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerServiceTestImpl.java
+++
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerServiceTestImpl.java
@@ -19,6 +19,7 @@
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.io.IOException;
+import java.time.Clock;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
@@ -46,6 +47,13 @@ public DiskBalancerServiceTestImpl(OzoneContainer container,
TimeUnit.MILLISECONDS, threadCount, conf);
}
+ public DiskBalancerServiceTestImpl(OzoneContainer container,
+ int serviceInterval, ConfigurationSource conf, int threadCount,
+ Clock clock) throws IOException {
+ super(container, serviceInterval, SERVICE_TIMEOUT_IN_MILLISECONDS,
+ TimeUnit.MILLISECONDS, threadCount, conf, clock);
+ }
+
public void runBalanceTasks() {
if (latch.getCount() > 0) {
this.latch.countDown();
diff --git
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/TestDiskBalancerTask.java
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/TestDiskBalancerTask.java
index fc3fdb7b140..7e4b49ccb40 100644
---
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/TestDiskBalancerTask.java
+++
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/TestDiskBalancerTask.java
@@ -47,7 +47,6 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.apache.commons.io.FileUtils;
import org.apache.hadoop.hdds.HddsConfigKeys;
@@ -83,6 +82,7 @@
import org.apache.hadoop.ozone.container.ozoneimpl.OzoneContainer;
import org.apache.ozone.test.GenericTestUtils;
import org.apache.ozone.test.GenericTestUtils.LogCapturer;
+import org.apache.ozone.test.TestClock;
import org.assertj.core.api.Fail;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
@@ -113,6 +113,7 @@ public class TestDiskBalancerTask {
private HddsVolume sourceVolume;
private HddsVolume destVolume;
private DiskBalancerServiceTestImpl diskBalancerService;
+ private TestClock clock;
private static final long CONTAINER_ID = 1L;
private static final long CONTAINER_SIZE = 1024L * 1024L; // 1 MB
@@ -243,8 +244,9 @@ public void setup() throws Exception {
DiskBalancerConfiguration diskBalancerConfiguration =
conf.getObject(DiskBalancerConfiguration.class);
diskBalancerConfiguration.setDiskBalancerShouldRun(true);
conf.setFromObject(diskBalancerConfiguration);
+ clock = TestClock.newInstance();
diskBalancerService = new DiskBalancerServiceTestImpl(ozoneContainer,
- 100, conf, 1);
+ 100, conf, 1, clock);
diskBalancerService.setReplicaDeletionDelay(0);
KeyValueContainer.setInjector(kvFaultInjector);
}
@@ -599,10 +601,8 @@ public void
testOldReplicaDelayedDeletion(ContainerTestVersionInfo versionInfo)
// create another container to trigger the deletion of old replicas
createContainer(CONTAINER_ID + 1, sourceVolume, State.CLOSED);
task = getTask();
- // Wait until the delayed deletion is eligible, then trigger cleanup.
- long deletionEligibleAt = System.nanoTime() +
TimeUnit.MILLISECONDS.toNanos(delay);
- GenericTestUtils.waitFor(
- () -> System.nanoTime() >= deletionEligibleAt, 50, 12_000);
+ // Advance the injected clock until the delayed deletion is eligible.
+ clock.fastForward(delay);
task.call();
// Verify that the old container is deleted
assertFalse(oldContainerDir.exists());
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]