Skip to content

Commit 9fb0035

Browse files
committed
Merge branch 'master' into HDDS-13223
2 parents cfc44f0 + 2ff58b3 commit 9fb0035

File tree

7 files changed

+86
-30
lines changed

7 files changed

+86
-30
lines changed

hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/StorageVolumeScannerMetrics.java renamed to hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/BackgroundVolumeScannerMetrics.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@
2626
import org.apache.hadoop.metrics2.lib.MutableGaugeLong;
2727

2828
/**
29-
* This class captures the Storage Volume Scanner Metrics.
29+
* This class captures the Background Storage Volume Scanner Metrics.
3030
**/
3131
@InterfaceAudience.Private
32-
@Metrics(about = "Storage Volume Scanner Metrics", context = "dfs")
33-
public class StorageVolumeScannerMetrics {
34-
public static final String SOURCE_NAME = StorageVolumeScannerMetrics.class.getSimpleName();
32+
@Metrics(about = "Background Volume Scanner Metrics", context = "dfs")
33+
public class BackgroundVolumeScannerMetrics {
34+
public static final String SOURCE_NAME = BackgroundVolumeScannerMetrics.class.getSimpleName();
3535

3636
@Metric("number of volumes scanned in the last iteration")
3737
private MutableGaugeLong numVolumesScannedInLastIteration;
@@ -49,12 +49,12 @@ public class StorageVolumeScannerMetrics {
4949
"since the last iteration had not elapsed")
5050
private MutableCounterLong numIterationsSkipped;
5151

52-
public StorageVolumeScannerMetrics() {
52+
public BackgroundVolumeScannerMetrics() {
5353
}
5454

55-
public static StorageVolumeScannerMetrics create() {
55+
public static BackgroundVolumeScannerMetrics create() {
5656
MetricsSystem ms = DefaultMetricsSystem.instance();
57-
return ms.register(SOURCE_NAME, "Storage Volume Scanner Metrics", new StorageVolumeScannerMetrics());
57+
return ms.register(SOURCE_NAME, "Background Volume Scanner Metrics", new BackgroundVolumeScannerMetrics());
5858
}
5959

6060
/**

hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/StorageVolumeChecker.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public class StorageVolumeChecker {
6565

6666
private AsyncChecker<Boolean, VolumeCheckResult> delegateChecker;
6767

68-
private final StorageVolumeScannerMetrics metrics;
68+
private final BackgroundVolumeScannerMetrics metrics;
6969

7070
/**
7171
* Max allowed time for a disk check in milliseconds. If the check
@@ -105,7 +105,7 @@ public class StorageVolumeChecker {
105105
public StorageVolumeChecker(ConfigurationSource conf, Timer timer,
106106
String threadNamePrefix) {
107107

108-
metrics = StorageVolumeScannerMetrics.create();
108+
metrics = BackgroundVolumeScannerMetrics.create();
109109

110110
this.timer = timer;
111111

@@ -441,7 +441,7 @@ void setDelegateChecker(
441441
}
442442

443443
@VisibleForTesting
444-
public StorageVolumeScannerMetrics getMetrics() {
444+
public BackgroundVolumeScannerMetrics getMetrics() {
445445
return metrics;
446446
}
447447
}

hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/volume/TestPeriodicVolumeChecker.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public void testPeriodicVolumeChecker(TestInfo testInfo) throws Exception {
7979
FakeTimer timer = new FakeTimer();
8080

8181
StorageVolumeChecker volumeChecker = new StorageVolumeChecker(conf, timer, "");
82-
StorageVolumeScannerMetrics metrics = volumeChecker.getMetrics();
82+
BackgroundVolumeScannerMetrics metrics = volumeChecker.getMetrics();
8383

8484
try {
8585
volumeChecker.registerVolumeSet(new ImmutableVolumeSet(makeVolumes(2, HEALTHY)));

hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/balancer/ContainerBalancer.java

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -308,16 +308,13 @@ private void startBalancingThread(int nextIterationIndex,
308308
}
309309

310310
/**
311-
* Validates balancer's state based on the specified expectedRunning.
311+
* Validates balancer's eligibility based on SCM state.
312312
* Confirms SCM is leader-ready and out of safe mode.
313313
*
314-
* @param expectedRunning true if ContainerBalancer is expected to be
315-
* running, else false
316314
* @throws IllegalContainerBalancerStateException if SCM is not
317-
* leader-ready, is in safe mode, or state does not match the specified
318-
* expected state
315+
* leader-ready or is in safe mode
319316
*/
320-
private void validateState(boolean expectedRunning)
317+
private void validateEligibility()
321318
throws IllegalContainerBalancerStateException {
322319
if (!scmContext.isLeaderReady()) {
323320
LOG.warn("SCM is not leader ready");
@@ -328,6 +325,19 @@ private void validateState(boolean expectedRunning)
328325
LOG.warn("SCM is in safe mode");
329326
throw new IllegalContainerBalancerStateException("SCM is in safe mode");
330327
}
328+
}
329+
330+
/**
331+
* Validates balancer's state based on the specified expectedRunning.
332+
*
333+
* @param expectedRunning true if ContainerBalancer is expected to be
334+
* running, else false
335+
* @throws IllegalContainerBalancerStateException if state does not
336+
* match the specified expected state
337+
*/
338+
private void validateState(boolean expectedRunning)
339+
throws IllegalContainerBalancerStateException {
340+
validateEligibility();
331341
if (!expectedRunning && !canBalancerStart()) {
332342
throw new IllegalContainerBalancerStateException(
333343
"Expect ContainerBalancer as not running state" +
@@ -387,18 +397,22 @@ private static void blockTillTaskStop(Thread balancingThread) {
387397
*/
388398
public void stopBalancer()
389399
throws IOException, IllegalContainerBalancerStateException {
390-
Thread balancingThread;
400+
Thread balancingThread = null;
391401
lock.lock();
392402
try {
393-
validateState(true);
403+
validateEligibility();
394404
saveConfiguration(config, false, 0);
395-
LOG.info("Trying to stop ContainerBalancer service.");
396-
task.stop();
397-
balancingThread = currentBalancingThread;
405+
if (isBalancerRunning()) {
406+
LOG.info("Trying to stop ContainerBalancer service.");
407+
task.stop();
408+
balancingThread = currentBalancingThread;
409+
}
398410
} finally {
399411
lock.unlock();
400412
}
401-
blockTillTaskStop(balancingThread);
413+
if (balancingThread != null) {
414+
blockTillTaskStop(balancingThread);
415+
}
402416
}
403417

404418
public void saveConfiguration(ContainerBalancerConfiguration configuration,

hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/balancer/TestContainerBalancer.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import static org.apache.hadoop.hdds.HddsConfigKeys.HDDS_NODE_REPORT_INTERVAL;
2121
import static org.apache.hadoop.hdds.HddsConfigKeys.HDDS_SCM_WAIT_TIME_AFTER_SAFE_MODE_EXIT;
2222
import static org.assertj.core.api.Assertions.assertThat;
23+
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
2324
import static org.junit.jupiter.api.Assertions.assertEquals;
2425
import static org.junit.jupiter.api.Assertions.assertFalse;
2526
import static org.junit.jupiter.api.Assertions.assertSame;
@@ -128,6 +129,8 @@ public void testShouldRun() throws Exception {
128129

129130
@Test
130131
public void testStartBalancerStop() throws Exception {
132+
//stop should not throw an exception as it is idempotent
133+
assertDoesNotThrow(() -> containerBalancer.stopBalancer());
131134
startBalancer(balancerConfiguration);
132135
assertThrows(IllegalContainerBalancerStateException.class,
133136
() -> containerBalancer.startBalancer(balancerConfiguration),
@@ -142,9 +145,9 @@ public void testStartBalancerStop() throws Exception {
142145
stopBalancer();
143146
assertSame(ContainerBalancerTask.Status.STOPPED, containerBalancer.getBalancerStatus());
144147

145-
assertThrows(Exception.class,
146-
() -> containerBalancer.stopBalancer(),
147-
"Exception should be thrown when stop again");
148+
// If the balancer is already stopped, the stop command should do nothing
149+
// and return successfully as stopBalancer is idempotent
150+
assertDoesNotThrow(() -> containerBalancer.stopBalancer());
148151
}
149152

150153
@Test

hadoop-ozone/freon/src/main/java/org/apache/hadoop/ozone/freon/BaseFreonGenerator.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@
2626
import io.opentelemetry.api.trace.StatusCode;
2727
import java.io.IOException;
2828
import java.io.InputStream;
29-
import java.time.Duration;
30-
import java.time.Instant;
3129
import java.util.LinkedList;
3230
import java.util.List;
3331
import java.util.concurrent.ExecutorService;
@@ -327,8 +325,7 @@ public void init() {
327325
LongSupplier supplier;
328326
if (duration != null) {
329327
maxValue = durationInSecond;
330-
supplier = () -> Duration.between(
331-
Instant.ofEpochMilli(startTime), Instant.now()).getSeconds();
328+
supplier = () -> (Time.monotonicNow() - startTime) / 1000;
332329
} else {
333330
maxValue = testNo;
334331
supplier = () -> successCounter.get() + failureCounter.get();

hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestContainerBalancerOperations.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919

2020
import static java.util.concurrent.TimeUnit.SECONDS;
2121
import static org.apache.hadoop.hdds.HddsConfigKeys.HDDS_NODE_REPORT_INTERVAL;
22+
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
2223
import static org.junit.jupiter.api.Assertions.assertEquals;
2324
import static org.junit.jupiter.api.Assertions.assertFalse;
2425
import static org.junit.jupiter.api.Assertions.assertTrue;
2526

27+
import java.io.IOException;
2628
import java.util.Optional;
2729
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
2830
import org.apache.hadoop.hdds.scm.PlacementPolicy;
@@ -178,4 +180,44 @@ public void testIfCBCLIOverridesConfigs() throws Exception {
178180
running = containerBalancerClient.getContainerBalancerStatus();
179181
assertFalse(running);
180182
}
183+
184+
/**
185+
* Tests that stopBalancer is idempotent - once the balancer is in STOPPED state,
186+
* invoking stop again should be a no-op and return successfully with exit code 0.
187+
*/
188+
@Test
189+
public void testStopBalancerIdempotent() throws IOException {
190+
boolean running = containerBalancerClient.getContainerBalancerStatus();
191+
assertFalse(running);
192+
assertDoesNotThrow(() -> containerBalancerClient.stopContainerBalancer());
193+
194+
Optional<Double> threshold = Optional.of(0.1);
195+
Optional<Integer> iterations = Optional.of(10000);
196+
Optional<Integer> maxDatanodesPercentageToInvolvePerIteration =
197+
Optional.of(100);
198+
Optional<Long> maxSizeToMovePerIterationInGB = Optional.of(1L);
199+
Optional<Long> maxSizeEnteringTargetInGB = Optional.of(6L);
200+
Optional<Long> maxSizeLeavingSourceInGB = Optional.of(6L);
201+
Optional<Integer> balancingInterval = Optional.of(70);
202+
Optional<Integer> moveTimeout = Optional.of(65);
203+
Optional<Integer> moveReplicationTimeout = Optional.of(50);
204+
Optional<Boolean> networkTopologyEnable = Optional.of(false);
205+
Optional<String> includeNodes = Optional.of("");
206+
Optional<String> excludeNodes = Optional.of("");
207+
containerBalancerClient.startContainerBalancer(threshold, iterations,
208+
maxDatanodesPercentageToInvolvePerIteration,
209+
maxSizeToMovePerIterationInGB, maxSizeEnteringTargetInGB,
210+
maxSizeLeavingSourceInGB, balancingInterval, moveTimeout,
211+
moveReplicationTimeout, networkTopologyEnable, includeNodes,
212+
excludeNodes);
213+
running = containerBalancerClient.getContainerBalancerStatus();
214+
assertTrue(running);
215+
216+
containerBalancerClient.stopContainerBalancer();
217+
running = containerBalancerClient.getContainerBalancerStatus();
218+
assertFalse(running);
219+
220+
// Calling stop balancer again should not throw an exception
221+
assertDoesNotThrow(() -> containerBalancerClient.stopContainerBalancer());
222+
}
181223
}

0 commit comments

Comments
 (0)