This is an automated email from the ASF dual-hosted git repository.
weichiu pushed a commit to branch HDDS-7593
in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/HDDS-7593 by this push:
new 6c6dc4352e HDDS-11135. [hsync] Replace expensive
VolumeUsage.getMinVolumeFreeSpace() (#6930)
6c6dc4352e is described below
commit 6c6dc4352e475c56a5972f8fe355c0aca2a6554c
Author: Wei-Chiu Chuang <[email protected]>
AuthorDate: Tue Jul 16 10:23:54 2024 -0700
HDDS-11135. [hsync] Replace expensive VolumeUsage.getMinVolumeFreeSpace()
(#6930)
Co-authored-by: Duong Nguyen <[email protected]>
---
.../container/common/impl/HddsDispatcher.java | 4 +-
.../common/impl/StorageLocationReport.java | 2 +-
.../common/volume/AvailableSpaceFilter.java | 2 +-
.../ozone/container/common/volume/VolumeUsage.java | 72 ++++++++++++++--------
.../common/volume/TestReservedVolumeSpace.java | 26 ++++++++
5 files changed, 76 insertions(+), 30 deletions(-)
diff --git
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/impl/HddsDispatcher.java
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/impl/HddsDispatcher.java
index 8d7dc087c6..3f7b752b1c 100644
---
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/impl/HddsDispatcher.java
+++
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/impl/HddsDispatcher.java
@@ -113,6 +113,7 @@ public class HddsDispatcher implements ContainerDispatcher,
Auditor {
private ContainerMetrics metrics;
private final TokenVerifier tokenVerifier;
private long slowOpThresholdMs;
+ private VolumeUsage.MinFreeSpaceCalculator freeSpaceCalculator;
/**
* Constructs an OzoneContainer that receives calls from
@@ -147,6 +148,7 @@ public class HddsDispatcher implements ContainerDispatcher,
Auditor {
LOG,
HddsUtils::processForDebug,
HddsUtils::processForDebug);
+ this.freeSpaceCalculator = new VolumeUsage.MinFreeSpaceCalculator(conf);
}
@Override
@@ -612,7 +614,7 @@ public class HddsDispatcher implements ContainerDispatcher,
Auditor {
volume.getCurrentUsage();
long volumeCapacity = precomputedVolumeSpace.getCapacity();
long volumeFreeSpaceToSpare =
- VolumeUsage.getMinVolumeFreeSpace(conf, volumeCapacity);
+ freeSpaceCalculator.get(volumeCapacity);
long volumeFree = precomputedVolumeSpace.getAvailable();
long volumeCommitted = volume.getCommittedBytes();
long volumeAvailable = volumeFree - volumeCommitted;
diff --git
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/impl/StorageLocationReport.java
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/impl/StorageLocationReport.java
index f31d45a778..dfcedbe75e 100644
---
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/impl/StorageLocationReport.java
+++
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/impl/StorageLocationReport.java
@@ -189,7 +189,7 @@ public final class StorageLocationReport implements
.setStorageLocation(getStorageLocation())
.setFailed(isFailed())
.setFreeSpaceToSpare(conf != null ?
- VolumeUsage.getMinVolumeFreeSpace(conf, getCapacity()) : 0)
+ new VolumeUsage.MinFreeSpaceCalculator(conf).get(getCapacity()) :
0)
.build();
}
diff --git
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/AvailableSpaceFilter.java
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/AvailableSpaceFilter.java
index 622c85a52f..0d82a38d1c 100644
---
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/AvailableSpaceFilter.java
+++
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/AvailableSpaceFilter.java
@@ -43,7 +43,7 @@ public class AvailableSpaceFilter implements
Predicate<HddsVolume> {
long committed = vol.getCommittedBytes();
long available = free - committed;
long volumeFreeSpaceToSpare =
- VolumeUsage.getMinVolumeFreeSpace(vol.getConf(), volumeCapacity);
+ new
VolumeUsage.MinFreeSpaceCalculator(vol.getConf()).get(volumeCapacity);
boolean hasEnoughSpace = VolumeUsage.hasVolumeEnoughSpace(free, committed,
requiredSpace, volumeFreeSpaceToSpare);
diff --git
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/VolumeUsage.java
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/VolumeUsage.java
index d18998821b..7e138b0571 100644
---
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/VolumeUsage.java
+++
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/VolumeUsage.java
@@ -140,37 +140,55 @@ public class VolumeUsage {
}
/**
- * If 'hdds.datanode.volume.min.free.space' is defined,
- * it will be honored first. If it is not defined and
- * 'hdds.datanode.volume.min.free.space.' is defined,it will honor this
- * else it will fall back to 'hdds.datanode.volume.min.free.space.default'
+ * Convenience class to calculate minimum free space.
*/
- public static long getMinVolumeFreeSpace(ConfigurationSource conf,
- long capacity) {
- if (conf.isConfigured(
- HDDS_DATANODE_VOLUME_MIN_FREE_SPACE) && conf.isConfigured(
- HDDS_DATANODE_VOLUME_MIN_FREE_SPACE_PERCENT)) {
- LOG.error(
- "Both {} and {} are set. Set either one, not both. If both are set,"
- + "it will use default value which is {} as min free space",
- HDDS_DATANODE_VOLUME_MIN_FREE_SPACE,
- HDDS_DATANODE_VOLUME_MIN_FREE_SPACE_PERCENT,
- HDDS_DATANODE_VOLUME_MIN_FREE_SPACE_DEFAULT);
- }
-
- if (conf.isConfigured(HDDS_DATANODE_VOLUME_MIN_FREE_SPACE)) {
- return (long) conf.getStorageSize(HDDS_DATANODE_VOLUME_MIN_FREE_SPACE,
+ public static class MinFreeSpaceCalculator {
+ private final boolean minFreeSpaceConfigured;
+ private final boolean minFreeSpacePercentConfigured;
+ private final long freeSpace;
+ private float freeSpacePercent;
+ private final long defaultFreeSpace;
+ public MinFreeSpaceCalculator(ConfigurationSource conf) {
+ // cache these values to avoid repeated lookups
+ minFreeSpaceConfigured =
conf.isConfigured(HDDS_DATANODE_VOLUME_MIN_FREE_SPACE);
+ minFreeSpacePercentConfigured =
conf.isConfigured(HDDS_DATANODE_VOLUME_MIN_FREE_SPACE_PERCENT);
+ freeSpace =
(long)conf.getStorageSize(HDDS_DATANODE_VOLUME_MIN_FREE_SPACE,
HDDS_DATANODE_VOLUME_MIN_FREE_SPACE_DEFAULT, StorageUnit.BYTES);
- } else if (conf.isConfigured(HDDS_DATANODE_VOLUME_MIN_FREE_SPACE_PERCENT))
{
- float volumeMinFreeSpacePercent = Float.parseFloat(
- conf.get(HDDS_DATANODE_VOLUME_MIN_FREE_SPACE_PERCENT));
- return (long) (capacity * volumeMinFreeSpacePercent);
+ if (minFreeSpacePercentConfigured) {
+ freeSpacePercent = Float.parseFloat(
+ conf.get(HDDS_DATANODE_VOLUME_MIN_FREE_SPACE_PERCENT));
+ }
+ StorageSize measure =
StorageSize.parse(HDDS_DATANODE_VOLUME_MIN_FREE_SPACE_DEFAULT);
+ double byteValue = measure.getUnit().toBytes(measure.getValue());
+ defaultFreeSpace = (long)StorageUnit.BYTES.fromBytes(byteValue);
}
- // either properties are not configured,then return
- // HDDS_DATANODE_VOLUME_MIN_FREE_SPACE_DEFAULT,
- return (long) conf.getStorageSize(HDDS_DATANODE_VOLUME_MIN_FREE_SPACE,
- HDDS_DATANODE_VOLUME_MIN_FREE_SPACE_DEFAULT, StorageUnit.BYTES);
+ /**
+ * If 'hdds.datanode.volume.min.free.space' is defined,
+ * it will be honored first. If it is not defined and
+ * 'hdds.datanode.volume.min.free.space' is defined, it will honor this
+ * else it will fall back to 'hdds.datanode.volume.min.free.space.default'
+ */
+ public long get(long capacity) {
+ if (minFreeSpaceConfigured && minFreeSpacePercentConfigured) {
+ LOG.error(
+ "Both {} and {} are set. Set either one, not both. If both are
set,"
+ + "it will use default value which is {} as min free space",
+ HDDS_DATANODE_VOLUME_MIN_FREE_SPACE,
+ HDDS_DATANODE_VOLUME_MIN_FREE_SPACE_PERCENT,
+ HDDS_DATANODE_VOLUME_MIN_FREE_SPACE_DEFAULT);
+ return defaultFreeSpace;
+ }
+
+ if (minFreeSpaceConfigured) {
+ return freeSpace;
+ } else if (minFreeSpacePercentConfigured) {
+ return (long) (capacity * freeSpacePercent);
+ }
+ // either properties are not configured,then return
+ // HDDS_DATANODE_VOLUME_MIN_FREE_SPACE_DEFAULT
+ return defaultFreeSpace;
+ }
}
public static boolean hasVolumeEnoughSpace(long volumeAvailableSpace,
diff --git
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/volume/TestReservedVolumeSpace.java
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/volume/TestReservedVolumeSpace.java
index cd9beab4b7..5e2dd0c75c 100644
---
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/volume/TestReservedVolumeSpace.java
+++
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/volume/TestReservedVolumeSpace.java
@@ -18,6 +18,8 @@
package org.apache.hadoop.ozone.container.common.volume;
+import org.apache.hadoop.conf.StorageUnit;
+import org.apache.hadoop.hdds.HddsConfigKeys;
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
import org.apache.hadoop.hdds.fs.MockSpaceUsageCheckFactory;
import org.apache.hadoop.hdds.scm.ScmConfigKeys;
@@ -30,6 +32,8 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.UUID;
+import static
org.apache.hadoop.hdds.HddsConfigKeys.HDDS_DATANODE_VOLUME_MIN_FREE_SPACE;
+import static
org.apache.hadoop.hdds.HddsConfigKeys.HDDS_DATANODE_VOLUME_MIN_FREE_SPACE_PERCENT;
import static
org.apache.hadoop.hdds.scm.ScmConfigKeys.HDDS_DATANODE_DIR_DU_RESERVED_PERCENT;
import static
org.apache.hadoop.hdds.scm.ScmConfigKeys.HDDS_DATANODE_DIR_DU_RESERVED_PERCENT_DEFAULT;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -178,6 +182,28 @@ public class TestReservedVolumeSpace {
assertEquals(500, reservedFromVolume);
}
+ @Test
+ public void testMinFreeSpaceCalculator() throws Exception {
+ OzoneConfiguration conf = new OzoneConfiguration();
+ double minSpace = 100.0;
+ conf.setStorageSize(HddsConfigKeys.HDDS_DATANODE_VOLUME_MIN_FREE_SPACE,
+ minSpace, StorageUnit.BYTES);
+ VolumeUsage.MinFreeSpaceCalculator calc = new
VolumeUsage.MinFreeSpaceCalculator(conf);
+ long capacity = 1000;
+ assertEquals(minSpace, calc.get(capacity));
+
+ conf.setFloat(HDDS_DATANODE_VOLUME_MIN_FREE_SPACE_PERCENT, 0.01f);
+ calc = new VolumeUsage.MinFreeSpaceCalculator(conf);
+ // default is 5GB
+ assertEquals(5L * 1024 * 1024 * 1024, calc.get(capacity));
+
+ // capacity * 1% = 10
+ conf.unset(HDDS_DATANODE_VOLUME_MIN_FREE_SPACE);
+ calc = new VolumeUsage.MinFreeSpaceCalculator(conf);
+ assertEquals(10, calc.get(capacity));
+ }
+
+
private long getExpectedDefaultReserved(HddsVolume volume) {
long totalCapacity =
volume.getVolumeInfo().get().getUsageForTesting().realUsage().getCapacity();
return (long) Math.ceil(totalCapacity *
HDDS_DATANODE_DIR_DU_RESERVED_PERCENT_DEFAULT);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]