diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/interfaces/Container.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/interfaces/Container.java index 19d61a4a1c1a..64e1a8bea2f3 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/interfaces/Container.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/interfaces/Container.java @@ -30,6 +30,7 @@ import org.apache.hadoop.hdfs.util.DataTransferThrottler; import org.apache.hadoop.ozone.container.common.impl.ContainerData; import org.apache.hadoop.ozone.container.common.volume.VolumeSet; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; /** * Interface for Container Operations. @@ -102,7 +103,7 @@ public Throwable getException() { * @throws StorageContainerException */ void create(VolumeSet volumeSet, VolumeChoosingPolicy volumeChoosingPolicy, - String scmId) throws StorageContainerException; + MinFreeSpaceCalculator minFreeSpaceCalculator, String scmId) throws StorageContainerException; /** * Deletes the container. diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/interfaces/VolumeChoosingPolicy.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/interfaces/VolumeChoosingPolicy.java index 72d05d38739c..c1b73ac73a13 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/interfaces/VolumeChoosingPolicy.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/interfaces/VolumeChoosingPolicy.java @@ -21,6 +21,7 @@ import java.util.List; import org.apache.hadoop.hdds.annotation.InterfaceAudience; import org.apache.hadoop.ozone.container.common.volume.HddsVolume; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; /** * This interface specifies the policy for choosing volumes to store replicas. @@ -37,9 +38,11 @@ public interface VolumeChoosingPolicy { * @param volumes - a list of available volumes. * @param maxContainerSize - the maximum size of the container for which a * volume is sought. + * @param freeSpaceCalculator - calculator for determining minimum free space * @return the chosen volume. * @throws IOException when disks are unavailable or are full. */ - HddsVolume chooseVolume(List volumes, long maxContainerSize) + HddsVolume chooseVolume(List volumes, long maxContainerSize, + MinFreeSpaceCalculator freeSpaceCalculator) throws IOException; } 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 330cc1d9f39a..a87016f721e6 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 @@ -21,6 +21,7 @@ import java.util.Map; import java.util.function.Predicate; import org.apache.hadoop.hdds.fs.SpaceUsageSource; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; /** * Filter for selecting volumes with enough space for a new container. @@ -32,9 +33,12 @@ public class AvailableSpaceFilter implements Predicate { private final Map fullVolumes = new HashMap<>(); private long mostAvailableSpace = Long.MIN_VALUE; + private final MinFreeSpaceCalculator freeSpaceCalculator; - AvailableSpaceFilter(long requiredSpace) { + AvailableSpaceFilter(long requiredSpace, + MinFreeSpaceCalculator freeSpaceCalculator) { this.requiredSpace = requiredSpace; + this.freeSpaceCalculator = freeSpaceCalculator; } @Override @@ -44,8 +48,7 @@ public boolean test(HddsVolume vol) { long free = usage.getAvailable(); long committed = vol.getCommittedBytes(); long available = free - committed; - long volumeFreeSpaceToSpare = - new VolumeUsage.MinFreeSpaceCalculator(vol.getConf()).get(volumeCapacity); + long volumeFreeSpaceToSpare = freeSpaceCalculator.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/CapacityVolumeChoosingPolicy.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/CapacityVolumeChoosingPolicy.java index 10794c8fa72a..8cd21f96413b 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/CapacityVolumeChoosingPolicy.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/CapacityVolumeChoosingPolicy.java @@ -25,6 +25,7 @@ import java.util.Random; import java.util.stream.Collectors; import org.apache.hadoop.ozone.container.common.interfaces.VolumeChoosingPolicy; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.util.DiskChecker.DiskOutOfSpaceException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,14 +50,16 @@ public class CapacityVolumeChoosingPolicy implements VolumeChoosingPolicy { @Override public HddsVolume chooseVolume(List volumes, - long maxContainerSize) throws IOException { + long maxContainerSize, + MinFreeSpaceCalculator freeSpaceCalculator) throws IOException { // No volumes available to choose from if (volumes.isEmpty()) { throw new DiskOutOfSpaceException("No more available volumes"); } - AvailableSpaceFilter filter = new AvailableSpaceFilter(maxContainerSize); + AvailableSpaceFilter filter = new AvailableSpaceFilter(maxContainerSize, + freeSpaceCalculator); List volumesWithEnoughSpace = volumes.stream() .filter(filter) diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/RoundRobinVolumeChoosingPolicy.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/RoundRobinVolumeChoosingPolicy.java index 1fe1e32f2b66..089a575beae6 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/RoundRobinVolumeChoosingPolicy.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/RoundRobinVolumeChoosingPolicy.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import org.apache.hadoop.ozone.container.common.interfaces.VolumeChoosingPolicy; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.util.DiskChecker.DiskOutOfSpaceException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,14 +43,16 @@ public class RoundRobinVolumeChoosingPolicy implements VolumeChoosingPolicy { @Override public HddsVolume chooseVolume(List volumes, - long maxContainerSize) throws IOException { + long maxContainerSize, + MinFreeSpaceCalculator freeSpaceCalculator) throws IOException { // No volumes available to choose from if (volumes.isEmpty()) { throw new DiskOutOfSpaceException("No more available volumes"); } - AvailableSpaceFilter filter = new AvailableSpaceFilter(maxContainerSize); + AvailableSpaceFilter filter = new AvailableSpaceFilter(maxContainerSize, + freeSpaceCalculator); // since volumes could've been removed because of the failure // make sure we are not out of bounds diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueContainer.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueContainer.java index dc944bcb1ca0..2a7d9b250062 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueContainer.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueContainer.java @@ -71,6 +71,7 @@ import org.apache.hadoop.ozone.container.common.utils.StorageVolumeUtil; import org.apache.hadoop.ozone.container.common.volume.HddsVolume; import org.apache.hadoop.ozone.container.common.volume.VolumeSet; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.ozone.container.keyvalue.helpers.BlockUtils; import org.apache.hadoop.ozone.container.keyvalue.helpers.KeyValueContainerLocationUtil; import org.apache.hadoop.ozone.container.keyvalue.helpers.KeyValueContainerUtil; @@ -138,8 +139,8 @@ public void setCheckChunksFilePath(boolean bCheckChunksDirFilePath) { } @Override - public void create(VolumeSet volumeSet, VolumeChoosingPolicy - volumeChoosingPolicy, String clusterId) throws StorageContainerException { + public void create(VolumeSet volumeSet, VolumeChoosingPolicy volumeChoosingPolicy, + MinFreeSpaceCalculator minFreeSpaceCalculator, String clusterId) throws StorageContainerException { Preconditions.checkNotNull(volumeChoosingPolicy, "VolumeChoosingPolicy " + "cannot be null"); Preconditions.checkNotNull(volumeSet, "VolumeSet cannot be null"); @@ -155,7 +156,7 @@ public void create(VolumeSet volumeSet, VolumeChoosingPolicy while (true) { HddsVolume containerVolume; try { - containerVolume = volumeChoosingPolicy.chooseVolume(volumes, maxSize); + containerVolume = volumeChoosingPolicy.chooseVolume(volumes, maxSize, minFreeSpaceCalculator); } catch (DiskOutOfSpaceException ex) { throw new StorageContainerException("Container creation failed, " + "due to disk out of space", ex, DISK_OUT_OF_SPACE); diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueHandler.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueHandler.java index 572d30d8db8a..060c5e74dfc6 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueHandler.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueHandler.java @@ -117,6 +117,7 @@ import org.apache.hadoop.ozone.container.common.volume.HddsVolume; import org.apache.hadoop.ozone.container.common.volume.VolumeChoosingPolicyFactory; import org.apache.hadoop.ozone.container.common.volume.VolumeSet; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.ozone.container.keyvalue.helpers.BlockUtils; import org.apache.hadoop.ozone.container.keyvalue.helpers.ChunkUtils; import org.apache.hadoop.ozone.container.keyvalue.helpers.KeyValueContainerUtil; @@ -150,6 +151,7 @@ public class KeyValueHandler extends Handler { private final Striped containerCreationLocks; private static FaultInjector injector; private final Clock clock; + private final MinFreeSpaceCalculator minFreeSpaceCalculator; public KeyValueHandler(ConfigurationSource config, String datanodeId, @@ -214,6 +216,7 @@ public KeyValueHandler(ConfigurationSource config, OzoneConfiguration.of(conf).set(ScmConfigKeys.OZONE_SCM_CONTAINER_LAYOUT_KEY, DEFAULT_LAYOUT.name()); } + this.minFreeSpaceCalculator = new MinFreeSpaceCalculator(conf); } @VisibleForTesting @@ -427,7 +430,7 @@ ContainerCommandResponseProto handleCreateContainer( containerIdLock.lock(); try { if (containerSet.getContainer(containerID) == null) { - newContainer.create(volumeSet, volumeChoosingPolicy, clusterId); + newContainer.create(volumeSet, volumeChoosingPolicy, minFreeSpaceCalculator, clusterId); if (RECOVERING == newContainer.getContainerState()) { created = containerSet.addContainerByOverwriteMissingContainer(newContainer); } else { diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/replication/ContainerImporter.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/replication/ContainerImporter.java index 46bbb6662015..2ee74511ff5f 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/replication/ContainerImporter.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/replication/ContainerImporter.java @@ -40,6 +40,7 @@ import org.apache.hadoop.ozone.container.common.volume.HddsVolume; import org.apache.hadoop.ozone.container.common.volume.MutableVolumeSet; import org.apache.hadoop.ozone.container.common.volume.VolumeChoosingPolicyFactory; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData; import org.apache.hadoop.ozone.container.keyvalue.TarContainerPacker; import org.apache.hadoop.ozone.container.ozoneimpl.ContainerController; @@ -60,6 +61,7 @@ public class ContainerImporter { private final ContainerController controller; private final MutableVolumeSet volumeSet; private final VolumeChoosingPolicy volumeChoosingPolicy; + private final MinFreeSpaceCalculator minFreeSpaceCalculator; private final long containerSize; private final Set importContainerProgress @@ -83,6 +85,7 @@ public ContainerImporter(@Nonnull ConfigurationSource conf, ScmConfigKeys.OZONE_SCM_CONTAINER_SIZE, ScmConfigKeys.OZONE_SCM_CONTAINER_SIZE_DEFAULT, StorageUnit.BYTES); this.conf = conf; + this.minFreeSpaceCalculator = new MinFreeSpaceCalculator(conf); } public boolean isAllowedContainerImport(long containerID) { @@ -149,7 +152,7 @@ HddsVolume chooseNextVolume() throws IOException { // Choose volume that can hold both container in tmp and dest directory return volumeChoosingPolicy.chooseVolume( StorageVolumeUtil.getHddsVolumesList(volumeSet.getVolumesList()), - containerSize * 2); + containerSize * 2, minFreeSpaceCalculator); } public static Path getUntarDirectory(HddsVolume hddsVolume) diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/ContainerTestUtils.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/ContainerTestUtils.java index 3cff94ed9bd6..e8a842a79c39 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/ContainerTestUtils.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/ContainerTestUtils.java @@ -68,6 +68,7 @@ import org.apache.hadoop.ozone.container.common.volume.HddsVolume; import org.apache.hadoop.ozone.container.common.volume.MutableVolumeSet; import org.apache.hadoop.ozone.container.common.volume.RoundRobinVolumeChoosingPolicy; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainer; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData; import org.apache.hadoop.ozone.container.keyvalue.helpers.KeyValueContainerUtil; @@ -277,6 +278,8 @@ public static KeyValueContainer addContainerToVolumeDir( throws IOException { VolumeChoosingPolicy volumeChoosingPolicy = new RoundRobinVolumeChoosingPolicy(); + MinFreeSpaceCalculator minFreeSpaceCalculator = + new MinFreeSpaceCalculator(conf); ContainerLayoutVersion layout = ContainerLayoutVersion.FILE_PER_BLOCK; KeyValueContainerData keyValueContainerData = new KeyValueContainerData( @@ -288,7 +291,7 @@ public static KeyValueContainer addContainerToVolumeDir( KeyValueContainer container = new KeyValueContainer(keyValueContainerData, conf); - container.create(volume.getVolumeSet(), volumeChoosingPolicy, clusterId); + container.create(volume.getVolumeSet(), volumeChoosingPolicy, minFreeSpaceCalculator, clusterId); container.close(); diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/TestBlockDeletingService.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/TestBlockDeletingService.java index 4e8ad609f2b5..fea1c86cf3a9 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/TestBlockDeletingService.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/TestBlockDeletingService.java @@ -88,6 +88,7 @@ import org.apache.hadoop.ozone.container.common.volume.MutableVolumeSet; import org.apache.hadoop.ozone.container.common.volume.RoundRobinVolumeChoosingPolicy; import org.apache.hadoop.ozone.container.common.volume.StorageVolume; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.ozone.container.keyvalue.ContainerTestVersionInfo; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainer; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData; @@ -181,7 +182,7 @@ private KeyValueContainerData createToDeleteBlocks(ContainerSet containerSet, data.setSchemaVersion(schemaVersion); KeyValueContainer container = new KeyValueContainer(data, conf); container.create(volumeSet, - new RoundRobinVolumeChoosingPolicy(), scmId); + new RoundRobinVolumeChoosingPolicy(), new MinFreeSpaceCalculator(conf), scmId); containerSet.addContainer(container); data = (KeyValueContainerData) containerSet.getContainer( containerID).getContainerData(); diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/TestSchemaTwoBackwardsCompatibility.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/TestSchemaTwoBackwardsCompatibility.java index 1dcc3be6c337..ef30d358fdf3 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/TestSchemaTwoBackwardsCompatibility.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/TestSchemaTwoBackwardsCompatibility.java @@ -61,6 +61,7 @@ import org.apache.hadoop.ozone.container.common.volume.MutableVolumeSet; import org.apache.hadoop.ozone.container.common.volume.RoundRobinVolumeChoosingPolicy; import org.apache.hadoop.ozone.container.common.volume.StorageVolume; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainer; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData; import org.apache.hadoop.ozone.container.keyvalue.KeyValueHandler; @@ -274,7 +275,7 @@ private KeyValueContainer createTestContainer() throws IOException { cData.setSchemaVersion(OzoneConsts.SCHEMA_V2); KeyValueContainer container = new KeyValueContainer(cData, conf); container.create(volumeSet, new RoundRobinVolumeChoosingPolicy(), - clusterID); + new MinFreeSpaceCalculator(conf), clusterID); // populate with some blocks // metadata will be updated here, too diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/TestStaleRecoveringContainerScrubbingService.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/TestStaleRecoveringContainerScrubbingService.java index 59e662db01bc..807903e27861 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/TestStaleRecoveringContainerScrubbingService.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/TestStaleRecoveringContainerScrubbingService.java @@ -22,6 +22,7 @@ import static org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerDataProto.State.UNHEALTHY; import static org.apache.hadoop.ozone.container.common.impl.ContainerImplTestUtils.newContainerSet; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.anyList; import static org.mockito.Mockito.anyLong; import static org.mockito.Mockito.mock; @@ -53,6 +54,7 @@ import org.apache.hadoop.ozone.container.common.volume.HddsVolume; import org.apache.hadoop.ozone.container.common.volume.MutableVolumeSet; import org.apache.hadoop.ozone.container.common.volume.RoundRobinVolumeChoosingPolicy; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.ozone.container.keyvalue.ContainerTestVersionInfo; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainer; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData; @@ -79,6 +81,7 @@ public class TestStaleRecoveringContainerScrubbingService { private int containerIdNum = 0; private MutableVolumeSet volumeSet; private RoundRobinVolumeChoosingPolicy volumeChoosingPolicy; + private MinFreeSpaceCalculator freeSpaceCalculator; private final TestClock testClock = new TestClock(Instant.now(), ZoneOffset.UTC); @@ -105,7 +108,8 @@ private void init() throws IOException { volumeSet = mock(MutableVolumeSet.class); volumeChoosingPolicy = mock(RoundRobinVolumeChoosingPolicy.class); - when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong())) + freeSpaceCalculator = mock(MinFreeSpaceCalculator.class); + when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong(), any(MinFreeSpaceCalculator.class))) .thenReturn(hddsVolume); } @@ -135,7 +139,7 @@ private List createTestContainers( new KeyValueContainer(recoveringContainerData, conf); recoveringKeyValueContainer.create( - volumeSet, volumeChoosingPolicy, clusterID); + volumeSet, volumeChoosingPolicy, freeSpaceCalculator, clusterID); containerSet.addContainer(recoveringKeyValueContainer); createdIds.add((long) containerIdNum); } diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/impl/TestContainerPersistence.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/impl/TestContainerPersistence.java index 0a31b9746d57..8df2ef692eaa 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/impl/TestContainerPersistence.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/impl/TestContainerPersistence.java @@ -81,6 +81,7 @@ import org.apache.hadoop.ozone.container.common.volume.MutableVolumeSet; import org.apache.hadoop.ozone.container.common.volume.RoundRobinVolumeChoosingPolicy; import org.apache.hadoop.ozone.container.common.volume.StorageVolume; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.ozone.container.keyvalue.ContainerTestVersionInfo; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainer; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData; @@ -117,6 +118,7 @@ public class TestContainerPersistence { private static String hddsPath; private static OzoneConfiguration conf; private static VolumeChoosingPolicy volumeChoosingPolicy; + private static MinFreeSpaceCalculator freeSpaceCalculator; private ContainerSet containerSet; private MutableVolumeSet volumeSet; @@ -143,6 +145,7 @@ public static void init() { conf.set(ScmConfigKeys.HDDS_DATANODE_DIR_KEY, hddsPath); conf.set(OzoneConfigKeys.OZONE_METADATA_DIRS, hddsPath); volumeChoosingPolicy = new RoundRobinVolumeChoosingPolicy(); + freeSpaceCalculator = new MinFreeSpaceCalculator(conf); } @AfterAll @@ -204,7 +207,7 @@ private KeyValueContainer addContainer(ContainerSet cSet, long cID) data.addMetadata("VOLUME", "shire"); data.addMetadata("owner)", "bilbo"); KeyValueContainer container = new KeyValueContainer(data, conf); - container.create(volumeSet, volumeChoosingPolicy, SCM_ID); + container.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, SCM_ID); commitBytesBefore = container.getContainerData() .getVolume().getCommittedBytes(); cSet.addContainer(container); diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/impl/TestHddsDispatcher.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/impl/TestHddsDispatcher.java index 5aca3bf1a39b..f5d891a61793 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/impl/TestHddsDispatcher.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/impl/TestHddsDispatcher.java @@ -89,6 +89,7 @@ import org.apache.hadoop.ozone.container.common.volume.RoundRobinVolumeChoosingPolicy; import org.apache.hadoop.ozone.container.common.volume.StorageVolume; import org.apache.hadoop.ozone.container.common.volume.VolumeSet; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.ozone.container.keyvalue.ContainerLayoutTestInfo; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainer; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData; @@ -140,7 +141,7 @@ public void testContainerCloseActionWhenFull( StorageVolumeUtil.getHddsVolumesList(volumeSet.getVolumesList()) .forEach(hddsVolume -> hddsVolume.setDbParentDir(tempDir.toFile())); container.create(volumeSet, new RoundRobinVolumeChoosingPolicy(), - scmId.toString()); + new MinFreeSpaceCalculator(conf), scmId.toString()); containerSet.addContainer(container); ContainerMetrics metrics = ContainerMetrics.create(conf); Map handlers = Maps.newHashMap(); @@ -277,7 +278,7 @@ public void testContainerCloseActionWhenVolumeFull( StorageVolumeUtil.getHddsVolumesList(volumeSet.getVolumesList()) .forEach(hddsVolume -> hddsVolume.setDbParentDir(tempDir.toFile())); container.create(volumeSet, new RoundRobinVolumeChoosingPolicy(), - scmId.toString()); + new MinFreeSpaceCalculator(conf), scmId.toString()); containerSet.addContainer(container); ContainerMetrics metrics = ContainerMetrics.create(conf); Map handlers = Maps.newHashMap(); @@ -311,7 +312,8 @@ public void testContainerCloseActionWhenVolumeFull( StorageContainerException scException = assertThrows(StorageContainerException.class, () -> container2.create(volumeSet, - new RoundRobinVolumeChoosingPolicy(), scmId.toString())); + new RoundRobinVolumeChoosingPolicy(), new MinFreeSpaceCalculator(conf), + scmId.toString())); assertEquals("Container creation failed, due to disk out of space", scException.getMessage()); } finally { diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/volume/TestCapacityVolumeChoosingPolicy.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/volume/TestCapacityVolumeChoosingPolicy.java index d6c97c5f1a36..1d537c5065af 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/volume/TestCapacityVolumeChoosingPolicy.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/volume/TestCapacityVolumeChoosingPolicy.java @@ -35,6 +35,7 @@ import org.apache.hadoop.hdds.fs.SpaceUsageCheckFactory; import org.apache.hadoop.hdds.fs.SpaceUsagePersistence; import org.apache.hadoop.hdds.fs.SpaceUsageSource; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.util.DiskChecker.DiskOutOfSpaceException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -113,7 +114,7 @@ public void testCapacityVolumeChoosingPolicy() throws Exception { // Test 1000 rounds of volume choosing for (int i = 0; i < 1000; i++) { - HddsVolume volume = policy.chooseVolume(volumes, 0); + HddsVolume volume = policy.chooseVolume(volumes, 0, new MinFreeSpaceCalculator(CONF)); chooseCount.put(volume, chooseCount.get(volume) + 1); } @@ -124,7 +125,7 @@ public void testCapacityVolumeChoosingPolicy() throws Exception { @Test public void throwsDiskOutOfSpaceIfRequestMoreThanAvailable() { Exception e = assertThrows(DiskOutOfSpaceException.class, - () -> policy.chooseVolume(volumes, 500)); + () -> policy.chooseVolume(volumes, 500, new MinFreeSpaceCalculator(CONF))); String msg = e.getMessage(); assertThat(msg) diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/volume/TestRoundRobinVolumeChoosingPolicy.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/volume/TestRoundRobinVolumeChoosingPolicy.java index 1c07fe7ab7b3..180929ce03c0 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/volume/TestRoundRobinVolumeChoosingPolicy.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/volume/TestRoundRobinVolumeChoosingPolicy.java @@ -32,6 +32,7 @@ import org.apache.hadoop.hdds.fs.SpaceUsageCheckFactory; import org.apache.hadoop.hdds.fs.SpaceUsagePersistence; import org.apache.hadoop.hdds.fs.SpaceUsageSource; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.util.DiskChecker.DiskOutOfSpaceException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -49,12 +50,14 @@ public class TestRoundRobinVolumeChoosingPolicy { private static final OzoneConfiguration CONF = new OzoneConfiguration(); @TempDir private Path baseDir; + private MinFreeSpaceCalculator minFreeSpaceCalculator; @BeforeEach public void setup() throws Exception { String volume1 = baseDir + "disk1"; String volume2 = baseDir + "disk2"; policy = new RoundRobinVolumeChoosingPolicy(); + minFreeSpaceCalculator = new MinFreeSpaceCalculator(CONF); // Use the exact capacity and availability specified in this test. Do not reserve space to prevent volumes from // filling up. @@ -94,21 +97,21 @@ public void testRRVolumeChoosingPolicy() throws Exception { assertEquals(200L, hddsVolume2.getCurrentUsage().getAvailable()); // Test two rounds of round-robin choosing - assertEquals(hddsVolume1, policy.chooseVolume(volumes, 0)); - assertEquals(hddsVolume2, policy.chooseVolume(volumes, 0)); - assertEquals(hddsVolume1, policy.chooseVolume(volumes, 0)); - assertEquals(hddsVolume2, policy.chooseVolume(volumes, 0)); + assertEquals(hddsVolume1, policy.chooseVolume(volumes, 0, minFreeSpaceCalculator)); + assertEquals(hddsVolume2, policy.chooseVolume(volumes, 0, minFreeSpaceCalculator)); + assertEquals(hddsVolume1, policy.chooseVolume(volumes, 0, minFreeSpaceCalculator)); + assertEquals(hddsVolume2, policy.chooseVolume(volumes, 0, minFreeSpaceCalculator)); // The first volume has only 100L space, so the policy should // choose the second one in case we ask for more. assertEquals(hddsVolume2, - policy.chooseVolume(volumes, 120)); + policy.chooseVolume(volumes, 120, minFreeSpaceCalculator)); } @Test public void throwsDiskOutOfSpaceIfRequestMoreThanAvailable() { Exception e = assertThrows(DiskOutOfSpaceException.class, - () -> policy.chooseVolume(volumes, 300)); + () -> policy.chooseVolume(volumes, 300, minFreeSpaceCalculator)); String msg = e.getMessage(); assertThat(msg).contains("No volumes have enough space for a new container. " + diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/volume/TestVolumeSetDiskChecks.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/volume/TestVolumeSetDiskChecks.java index 2c77b00bd56b..92632deec813 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/volume/TestVolumeSetDiskChecks.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/volume/TestVolumeSetDiskChecks.java @@ -57,6 +57,7 @@ import org.apache.hadoop.ozone.container.common.statemachine.DatanodeStateMachine; import org.apache.hadoop.ozone.container.common.statemachine.StateContext; import org.apache.hadoop.ozone.container.common.utils.StorageVolumeUtil; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainer; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData; import org.apache.hadoop.ozone.container.ozoneimpl.OzoneContainer; @@ -307,14 +308,16 @@ public void testVolumeFailure() throws IOException { StorageVolumeUtil.getHddsVolumesList(volumeSet.getVolumesList()) .forEach(hddsVolume -> hddsVolume.setDbParentDir(tempDir.toFile())); container.create(volumeSet, - new RoundRobinVolumeChoosingPolicy(), UUID.randomUUID().toString()); + new RoundRobinVolumeChoosingPolicy(), new MinFreeSpaceCalculator(conf), + UUID.randomUUID().toString()); conSet.addContainer(container); KeyValueContainer container1 = new KeyValueContainer(data1, conf); StorageVolumeUtil.getHddsVolumesList(volumeSet1.getVolumesList()) .forEach(hddsVolume -> hddsVolume.setDbParentDir(tempDir.toFile())); container1.create(volumeSet1, - new RoundRobinVolumeChoosingPolicy(), UUID.randomUUID().toString()); + new RoundRobinVolumeChoosingPolicy(), new MinFreeSpaceCalculator(conf), + UUID.randomUUID().toString()); conSet.addContainer(container1); DatanodeStateMachine datanodeStateMachineMock = mock(DatanodeStateMachine.class); diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueBlockIterator.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueBlockIterator.java index 577f65c2e583..c12826a3214c 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueBlockIterator.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueBlockIterator.java @@ -51,6 +51,7 @@ import org.apache.hadoop.ozone.container.common.volume.MutableVolumeSet; import org.apache.hadoop.ozone.container.common.volume.RoundRobinVolumeChoosingPolicy; import org.apache.hadoop.ozone.container.common.volume.StorageVolume; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.ozone.container.keyvalue.helpers.BlockUtils; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.io.TempDir; @@ -118,7 +119,7 @@ public void setup() throws Exception { // Init the container. container = new KeyValueContainer(containerData, conf); container.create(volumeSet, new RoundRobinVolumeChoosingPolicy(), - clusterID); + new MinFreeSpaceCalculator(conf), clusterID); db = BlockUtils.getDB(containerData, conf); } diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueContainer.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueContainer.java index 52478cf4b105..bd264f920ac7 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueContainer.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueContainer.java @@ -34,6 +34,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.anyList; import static org.mockito.Mockito.anyLong; import static org.mockito.Mockito.mock; @@ -84,6 +85,7 @@ import org.apache.hadoop.ozone.container.common.volume.RoundRobinVolumeChoosingPolicy; import org.apache.hadoop.ozone.container.common.volume.StorageVolume; import org.apache.hadoop.ozone.container.common.volume.VolumeSet; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.ozone.container.keyvalue.helpers.BlockUtils; import org.apache.hadoop.ozone.container.keyvalue.helpers.KeyValueContainerUtil; import org.apache.hadoop.ozone.container.metadata.AbstractDatanodeStore; @@ -107,6 +109,7 @@ public class TestKeyValueContainer { private String scmId = UUID.randomUUID().toString(); private VolumeSet volumeSet; private RoundRobinVolumeChoosingPolicy volumeChoosingPolicy; + private MinFreeSpaceCalculator freeSpaceCalculator; private KeyValueContainerData keyValueContainerData; private KeyValueContainer keyValueContainer; private UUID datanodeId; @@ -148,12 +151,13 @@ private void init(ContainerTestVersionInfo versionInfo) throws Exception { volumeSet = mock(MutableVolumeSet.class); volumeChoosingPolicy = mock(RoundRobinVolumeChoosingPolicy.class); + freeSpaceCalculator = mock(MinFreeSpaceCalculator.class); when(volumeSet.getVolumesList()) .thenAnswer(i -> hddsVolumes.stream() .map(v -> (StorageVolume) v) .collect(Collectors.toList())); when(volumeChoosingPolicy - .chooseVolume(anyList(), anyLong())).thenAnswer( + .chooseVolume(anyList(), anyLong(), any(MinFreeSpaceCalculator.class))).thenAnswer( invocation -> { List volumes = invocation.getArgument(0); return volumes.get(0); @@ -365,7 +369,7 @@ public void testContainerImportExport(ContainerTestVersionInfo versionInfo) KeyValueContainer container = new KeyValueContainer(containerData, CONF); HddsVolume containerVolume = volumeChoosingPolicy.chooseVolume( - StorageVolumeUtil.getHddsVolumesList(volumeSet.getVolumesList()), 1); + StorageVolumeUtil.getHddsVolumesList(volumeSet.getVolumesList()), 1, freeSpaceCalculator); container.populatePathFields(scmId, containerVolume); try (InputStream fis = Files.newInputStream(folderToExport.toPath())) { @@ -406,7 +410,7 @@ public void testContainerImportExport(ContainerTestVersionInfo versionInfo) container = new KeyValueContainer(containerData, CONF); containerVolume = volumeChoosingPolicy.chooseVolume( - StorageVolumeUtil.getHddsVolumesList(volumeSet.getVolumesList()), 1); + StorageVolumeUtil.getHddsVolumesList(volumeSet.getVolumesList()), 1, freeSpaceCalculator); container.populatePathFields(scmId, containerVolume); KeyValueContainer finalContainer1 = container; assertThrows(IOException.class, () -> { @@ -439,7 +443,7 @@ private void checkContainerFilesPresent(KeyValueContainerData data, * Create the container on disk. */ private void createContainer() throws StorageContainerException { - keyValueContainer.create(volumeSet, volumeChoosingPolicy, scmId); + keyValueContainer.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, scmId); keyValueContainerData = keyValueContainer.getContainerData(); } @@ -538,9 +542,9 @@ public void concurrentExport(ContainerTestVersionInfo versionInfo) public void testDuplicateContainer(ContainerTestVersionInfo versionInfo) throws Exception { init(versionInfo); - keyValueContainer.create(volumeSet, volumeChoosingPolicy, scmId); + keyValueContainer.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, scmId); StorageContainerException exception = assertThrows(StorageContainerException.class, () -> - keyValueContainer.create(volumeSet, volumeChoosingPolicy, scmId)); + keyValueContainer.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, scmId)); assertEquals(ContainerProtos.Result.CONTAINER_ALREADY_EXISTS, exception.getResult()); assertThat(exception).hasMessage("Container creation failed because ContainerFile already exists"); } @@ -550,11 +554,11 @@ public void testDiskFullExceptionCreateContainer( ContainerTestVersionInfo versionInfo) throws Exception { init(versionInfo); reset(volumeChoosingPolicy); - when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong())) + when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong(), any(MinFreeSpaceCalculator.class))) .thenThrow(DiskChecker.DiskOutOfSpaceException.class); StorageContainerException exception = assertThrows(StorageContainerException.class, () -> - keyValueContainer.create(volumeSet, volumeChoosingPolicy, scmId)); + keyValueContainer.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, scmId)); assertEquals(ContainerProtos.Result.DISK_OUT_OF_SPACE, exception.getResult()); assertThat(exception).hasMessage("Container creation failed, due to disk out of space"); } @@ -566,7 +570,7 @@ public void testDeleteContainer(ContainerTestVersionInfo versionInfo) closeContainer(); keyValueContainer = new KeyValueContainer( keyValueContainerData, CONF); - keyValueContainer.create(volumeSet, volumeChoosingPolicy, scmId); + keyValueContainer.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, scmId); KeyValueContainerUtil.removeContainer( keyValueContainer.getContainerData(), CONF); keyValueContainer.delete(); @@ -593,7 +597,7 @@ public void testDeleteContainer(ContainerTestVersionInfo versionInfo) public void testCloseContainer(ContainerTestVersionInfo versionInfo) throws Exception { init(versionInfo); - keyValueContainer.create(volumeSet, volumeChoosingPolicy, scmId); + keyValueContainer.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, scmId); keyValueContainer.close(); keyValueContainerData = keyValueContainer @@ -615,7 +619,7 @@ public void testCloseContainer(ContainerTestVersionInfo versionInfo) public void testReportOfUnhealthyContainer( ContainerTestVersionInfo versionInfo) throws Exception { init(versionInfo); - keyValueContainer.create(volumeSet, volumeChoosingPolicy, scmId); + keyValueContainer.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, scmId); assertNotNull(keyValueContainer.getContainerReport()); keyValueContainer.markContainerUnhealthy(); File containerFile = keyValueContainer.getContainerFile(); @@ -631,7 +635,7 @@ public void testReportOfUnhealthyContainer( public void testUpdateContainer(ContainerTestVersionInfo versionInfo) throws Exception { init(versionInfo); - keyValueContainer.create(volumeSet, volumeChoosingPolicy, scmId); + keyValueContainer.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, scmId); Map metadata = new HashMap<>(); metadata.put(OzoneConsts.VOLUME, OzoneConsts.OZONE); metadata.put(OzoneConsts.OWNER, OzoneConsts.OZONE_SIMPLE_HDFS_USER); @@ -660,7 +664,7 @@ public void testUpdateContainerUnsupportedRequest( StorageContainerException exception = assertThrows(StorageContainerException.class, () -> { keyValueContainer = new KeyValueContainer(keyValueContainerData, CONF); - keyValueContainer.create(volumeSet, volumeChoosingPolicy, scmId); + keyValueContainer.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, scmId); Map metadata = new HashMap<>(); metadata.put(OzoneConsts.VOLUME, OzoneConsts.OZONE); keyValueContainer.update(metadata, false); @@ -679,7 +683,7 @@ public void testContainerRocksDB(ContainerTestVersionInfo versionInfo) closeContainer(); keyValueContainer = new KeyValueContainer( keyValueContainerData, CONF); - keyValueContainer.create(volumeSet, volumeChoosingPolicy, scmId); + keyValueContainer.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, scmId); try (DBHandle db = BlockUtils.getDB(keyValueContainerData, CONF)) { RDBStore store = (RDBStore) db.getStore().getStore(); @@ -733,7 +737,7 @@ public void testDBProfileAffectsDBOptions( ContainerTestVersionInfo versionInfo) throws Exception { init(versionInfo); // Create Container 1 - keyValueContainer.create(volumeSet, volumeChoosingPolicy, scmId); + keyValueContainer.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, scmId); DatanodeDBProfile outProfile1; try (DBHandle db1 = @@ -754,7 +758,7 @@ public void testDBProfileAffectsDBOptions( (long) StorageUnit.GB.toBytes(5), UUID.randomUUID().toString(), datanodeId.toString()); keyValueContainer = new KeyValueContainer(keyValueContainerData, otherConf); - keyValueContainer.create(volumeSet, volumeChoosingPolicy, scmId); + keyValueContainer.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, scmId); DatanodeDBProfile outProfile2; try (DBHandle db2 = @@ -834,7 +838,7 @@ void testAutoCompactionSmallSstFile( List exportFiles = new ArrayList<>(); for (HddsVolume volume: volumeList) { reset(volumeChoosingPolicy); - when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong())) + when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong(), any(MinFreeSpaceCalculator.class))) .thenReturn(volume); for (int index = 0; index < count; index++, containerId++) { // Create new container @@ -842,7 +846,7 @@ void testAutoCompactionSmallSstFile( (long) StorageUnit.GB.toBytes(5), UUID.randomUUID().toString(), datanodeId.toString()); container = new KeyValueContainer(containerData, CONF); - container.create(volumeSet, volumeChoosingPolicy, scmId); + container.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, scmId); containerData = container.getContainerData(); containerData.setState(ContainerProtos.ContainerDataProto.State.CLOSED); populate(container, numberOfKeysToWrite); @@ -944,7 +948,7 @@ public void testIsEmptyContainerStateWhileImport( KeyValueContainer container = new KeyValueContainer(containerData, CONF); HddsVolume containerVolume = volumeChoosingPolicy.chooseVolume( - StorageVolumeUtil.getHddsVolumesList(volumeSet.getVolumesList()), 1); + StorageVolumeUtil.getHddsVolumesList(volumeSet.getVolumesList()), 1, freeSpaceCalculator); container.populatePathFields(scmId, containerVolume); try (InputStream fis = Files.newInputStream(folderToExport.toPath())) { @@ -992,7 +996,7 @@ public void testIsEmptyContainerStateWhileImportWithoutBlock( KeyValueContainer container = new KeyValueContainer(containerData, CONF); HddsVolume containerVolume = volumeChoosingPolicy.chooseVolume( - StorageVolumeUtil.getHddsVolumesList(volumeSet.getVolumesList()), 1); + StorageVolumeUtil.getHddsVolumesList(volumeSet.getVolumesList()), 1, freeSpaceCalculator); container.populatePathFields(scmId, containerVolume); try (InputStream fis = Files.newInputStream(folderToExport.toPath())) { @@ -1047,7 +1051,7 @@ private void testMixedSchemaImport(String dir, ContainerTestHelper.CONTAINER_MAX_SIZE, UUID.randomUUID().toString(), UUID.randomUUID().toString()); KeyValueContainer container = new KeyValueContainer(data, conf); - container.create(volumeSet, volumeChoosingPolicy, scmId); + container.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, scmId); long pendingDeleteBlockCount = 20; try (DBHandle meta = BlockUtils.getDB(data, conf)) { Table metadataTable = meta.getStore().getMetadataTable(); diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueContainerIntegrityChecks.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueContainerIntegrityChecks.java index 3b4cfff93790..af827e13b271 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueContainerIntegrityChecks.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueContainerIntegrityChecks.java @@ -43,6 +43,7 @@ import org.apache.hadoop.ozone.container.common.volume.MutableVolumeSet; import org.apache.hadoop.ozone.container.common.volume.RoundRobinVolumeChoosingPolicy; import org.apache.hadoop.ozone.container.common.volume.StorageVolume; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.ozone.container.keyvalue.helpers.BlockUtils; import org.apache.hadoop.ozone.container.keyvalue.interfaces.ChunkManager; import org.junit.jupiter.api.AfterEach; @@ -133,7 +134,7 @@ protected KeyValueContainer createContainerWithBlocks(long containerId, UUID.randomUUID().toString(), UUID.randomUUID().toString()); KeyValueContainer container = new KeyValueContainer(containerData, conf); container.create(volumeSet, new RoundRobinVolumeChoosingPolicy(), - clusterID); + new MinFreeSpaceCalculator(conf), clusterID); try (DBHandle metadataStore = BlockUtils.getDB(containerData, conf)) { assertNotNull(containerData.getChunksPath()); diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueContainerMarkUnhealthy.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueContainerMarkUnhealthy.java index bc6d5a675a3c..9378ffeedfdb 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueContainerMarkUnhealthy.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueContainerMarkUnhealthy.java @@ -21,6 +21,7 @@ import static org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerDataProto.State.UNHEALTHY; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.anyList; import static org.mockito.Mockito.anyLong; import static org.mockito.Mockito.mock; @@ -40,6 +41,7 @@ import org.apache.hadoop.ozone.container.common.volume.MutableVolumeSet; import org.apache.hadoop.ozone.container.common.volume.RoundRobinVolumeChoosingPolicy; import org.apache.hadoop.ozone.container.common.volume.VolumeSet; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Timeout; import org.junit.jupiter.api.io.TempDir; @@ -62,6 +64,7 @@ public class TestKeyValueContainerMarkUnhealthy { private String scmId = UUID.randomUUID().toString(); private VolumeSet volumeSet; private RoundRobinVolumeChoosingPolicy volumeChoosingPolicy; + private MinFreeSpaceCalculator freeSpaceCalculator; private KeyValueContainerData keyValueContainerData; private KeyValueContainer keyValueContainer; private UUID datanodeId; @@ -87,7 +90,8 @@ public void setup() throws Exception { volumeSet = mock(MutableVolumeSet.class); volumeChoosingPolicy = mock(RoundRobinVolumeChoosingPolicy.class); - when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong())) + freeSpaceCalculator = mock(MinFreeSpaceCalculator.class); + when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong(), any(MinFreeSpaceCalculator.class))) .thenReturn(hddsVolume); keyValueContainerData = new KeyValueContainerData(1L, @@ -153,7 +157,7 @@ public void testMarkClosedContainerAsUnhealthy(ContainerLayoutVersion layoutVers initTestData(layoutVersion); // We need to create the container so the compact-on-close operation // does not NPE. - keyValueContainer.create(volumeSet, volumeChoosingPolicy, scmId); + keyValueContainer.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, scmId); keyValueContainer.close(); keyValueContainer.markContainerUnhealthy(); assertThat(keyValueContainerData.getState()).isEqualTo(UNHEALTHY); @@ -167,7 +171,7 @@ public void testMarkQuasiClosedContainerAsUnhealthy(ContainerLayoutVersion layou initTestData(layoutVersion); // We need to create the container so the sync-on-quasi-close operation // does not NPE. - keyValueContainer.create(volumeSet, volumeChoosingPolicy, scmId); + keyValueContainer.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, scmId); keyValueContainer.quasiClose(); keyValueContainer.markContainerUnhealthy(); assertThat(keyValueContainerData.getState()).isEqualTo(UNHEALTHY); diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/impl/AbstractTestChunkManager.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/impl/AbstractTestChunkManager.java index 9126da70ea01..ecd03a25e29b 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/impl/AbstractTestChunkManager.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/impl/AbstractTestChunkManager.java @@ -21,6 +21,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.anyList; import static org.mockito.Mockito.anyLong; import static org.mockito.Mockito.mock; @@ -43,6 +44,7 @@ import org.apache.hadoop.ozone.container.common.volume.RoundRobinVolumeChoosingPolicy; import org.apache.hadoop.ozone.container.common.volume.VolumeIOStats; import org.apache.hadoop.ozone.container.common.volume.VolumeSet; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.ozone.container.keyvalue.ContainerLayoutTestInfo; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainer; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData; @@ -92,7 +94,9 @@ public final void setUp(@TempDir File confDir) throws Exception { RoundRobinVolumeChoosingPolicy volumeChoosingPolicy = mock(RoundRobinVolumeChoosingPolicy.class); - when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong())) + MinFreeSpaceCalculator minFreeSpaceCalculator = + mock(MinFreeSpaceCalculator.class); + when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong(), any(MinFreeSpaceCalculator.class))) .thenReturn(hddsVolume); keyValueContainerData = new KeyValueContainerData(1L, @@ -103,7 +107,7 @@ public final void setUp(@TempDir File confDir) throws Exception { keyValueContainer = new KeyValueContainer(keyValueContainerData, config); keyValueContainer.create(volumeSet, volumeChoosingPolicy, - UUID.randomUUID().toString()); + minFreeSpaceCalculator, UUID.randomUUID().toString()); header = "my header".getBytes(UTF_8); byte[] bytes = "testing write chunks".getBytes(UTF_8); diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/impl/TestBlockManagerImpl.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/impl/TestBlockManagerImpl.java index 07414d701aad..2794235dd62f 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/impl/TestBlockManagerImpl.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/impl/TestBlockManagerImpl.java @@ -22,6 +22,7 @@ import static org.apache.hadoop.ozone.container.keyvalue.impl.BlockManagerImpl.FULL_CHUNK; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.mock; @@ -45,6 +46,7 @@ import org.apache.hadoop.ozone.container.common.volume.MutableVolumeSet; import org.apache.hadoop.ozone.container.common.volume.RoundRobinVolumeChoosingPolicy; import org.apache.hadoop.ozone.container.common.volume.VolumeSet; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.ozone.container.keyvalue.ContainerTestVersionInfo; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainer; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData; @@ -64,6 +66,7 @@ public class TestBlockManagerImpl { private String scmId = UUID.randomUUID().toString(); private VolumeSet volumeSet; private RoundRobinVolumeChoosingPolicy volumeChoosingPolicy; + private MinFreeSpaceCalculator freeSpaceCalculator; private KeyValueContainerData keyValueContainerData; private KeyValueContainer keyValueContainer; private BlockData blockData; @@ -96,7 +99,8 @@ private void initilaze() throws Exception { volumeSet = mock(MutableVolumeSet.class); volumeChoosingPolicy = mock(RoundRobinVolumeChoosingPolicy.class); - when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong())) + freeSpaceCalculator = mock(MinFreeSpaceCalculator.class); + when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong(), any(MinFreeSpaceCalculator.class))) .thenReturn(hddsVolume); keyValueContainerData = new KeyValueContainerData(1L, @@ -107,7 +111,7 @@ private void initilaze() throws Exception { keyValueContainer = new KeyValueContainer( keyValueContainerData, config); - keyValueContainer.create(volumeSet, volumeChoosingPolicy, scmId); + keyValueContainer.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, scmId); // Creating BlockData blockID = new BlockID(1L, 1L); diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/ozoneimpl/TestContainerReader.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/ozoneimpl/TestContainerReader.java index e315ced9f48d..682e77e24518 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/ozoneimpl/TestContainerReader.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/ozoneimpl/TestContainerReader.java @@ -28,6 +28,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.anyList; import static org.mockito.Mockito.anyLong; import static org.mockito.Mockito.mock; @@ -63,6 +64,7 @@ import org.apache.hadoop.ozone.container.common.volume.RoundRobinVolumeChoosingPolicy; import org.apache.hadoop.ozone.container.common.volume.StorageVolume; import org.apache.hadoop.ozone.container.common.volume.VolumeSet; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.ozone.container.keyvalue.ContainerTestVersionInfo; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainer; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData; @@ -86,6 +88,7 @@ public class TestContainerReader { private RoundRobinVolumeChoosingPolicy volumeChoosingPolicy; + private MinFreeSpaceCalculator freeSpaceCalculator; private UUID datanodeId; private String clusterId = UUID.randomUUID().toString(); private int blockCount = 10; @@ -114,7 +117,8 @@ private void setup(ContainerTestVersionInfo versionInfo) throws Exception { volumeSet = mock(MutableVolumeSet.class); volumeChoosingPolicy = mock(RoundRobinVolumeChoosingPolicy.class); - when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong())) + freeSpaceCalculator = mock(MinFreeSpaceCalculator.class); + when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong(), any(MinFreeSpaceCalculator.class))) .thenReturn(hddsVolume); for (int i = 0; i < 2; i++) { @@ -125,7 +129,7 @@ private void setup(ContainerTestVersionInfo versionInfo) throws Exception { KeyValueContainer keyValueContainer = new KeyValueContainer(keyValueContainerData, conf); - keyValueContainer.create(volumeSet, volumeChoosingPolicy, clusterId); + keyValueContainer.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, clusterId); List blkNames; @@ -228,7 +232,7 @@ public void testContainerReader(ContainerTestVersionInfo versionInfo) new KeyValueContainer(recoveringContainerData, conf); recoveringKeyValueContainer.create( - volumeSet, volumeChoosingPolicy, clusterId); + volumeSet, volumeChoosingPolicy, freeSpaceCalculator, clusterId); ContainerReader containerReader = new ContainerReader(volumeSet, hddsVolume, containerSet, conf, true); @@ -280,7 +284,7 @@ public void testContainerReaderWithLoadException( StorageVolumeUtil.checkVolume(hddsVolume1, clusterId, clusterId, conf, null, null); volumeChoosingPolicy1 = mock(RoundRobinVolumeChoosingPolicy.class); - when(volumeChoosingPolicy1.chooseVolume(anyList(), anyLong())) + when(volumeChoosingPolicy1.chooseVolume(anyList(), anyLong(), any(MinFreeSpaceCalculator.class))) .thenReturn(hddsVolume1); int containerCount = 3; @@ -291,7 +295,7 @@ public void testContainerReaderWithLoadException( datanodeId.toString()); KeyValueContainer keyValueContainer = new KeyValueContainer(keyValueContainerData, conf); - keyValueContainer.create(volumeSet1, volumeChoosingPolicy1, clusterId); + keyValueContainer.create(volumeSet1, volumeChoosingPolicy1, freeSpaceCalculator, clusterId); if (i == 0) { // rename first container directory name @@ -330,7 +334,7 @@ public void testContainerReaderWithInvalidDbPath( StorageVolumeUtil.checkVolume(hddsVolume1, clusterId, clusterId, conf, null, null); volumeChoosingPolicy1 = mock(RoundRobinVolumeChoosingPolicy.class); - when(volumeChoosingPolicy1.chooseVolume(anyList(), anyLong())) + when(volumeChoosingPolicy1.chooseVolume(anyList(), anyLong(), any(MinFreeSpaceCalculator.class))) .thenReturn(hddsVolume1); List dbPathList = new ArrayList<>(); @@ -342,7 +346,7 @@ public void testContainerReaderWithInvalidDbPath( datanodeId.toString()); KeyValueContainer keyValueContainer = new KeyValueContainer(keyValueContainerData, conf); - keyValueContainer.create(volumeSet1, volumeChoosingPolicy1, clusterId); + keyValueContainer.create(volumeSet1, volumeChoosingPolicy1, freeSpaceCalculator, clusterId); dbPathList.add(keyValueContainerData.getDbFile()); } ContainerCache.getInstance(conf).shutdownCache(); @@ -513,7 +517,7 @@ private KeyValueContainer createContainerWithId(int id, VolumeSet volSet, KeyValueContainer keyValueContainer = new KeyValueContainer(keyValueContainerData, conf); - keyValueContainer.create(volSet, policy, clusterId); + keyValueContainer.create(volSet, policy, freeSpaceCalculator, clusterId); List blkNames; if (id % 2 == 0) { @@ -551,7 +555,7 @@ public void testMarkedDeletedContainerCleared( KeyValueContainer kvContainer = new KeyValueContainer(containerData, conf); kvContainer.create( - volumeSet, volumeChoosingPolicy, clusterId); + volumeSet, volumeChoosingPolicy, freeSpaceCalculator, clusterId); long baseCount = 0; if (containerData.hasSchema(OzoneConsts.SCHEMA_V3)) { // add db entry for the container ID 101 for V3 diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/ozoneimpl/TestOzoneContainer.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/ozoneimpl/TestOzoneContainer.java index 34619c19183f..3467fc67318f 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/ozoneimpl/TestOzoneContainer.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/ozoneimpl/TestOzoneContainer.java @@ -55,6 +55,7 @@ import org.apache.hadoop.ozone.container.common.volume.MutableVolumeSet; import org.apache.hadoop.ozone.container.common.volume.RoundRobinVolumeChoosingPolicy; import org.apache.hadoop.ozone.container.common.volume.StorageVolume; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.ozone.container.keyvalue.ContainerTestVersionInfo; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainer; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData; @@ -74,6 +75,7 @@ public class TestOzoneContainer { private String clusterId = UUID.randomUUID().toString(); private MutableVolumeSet volumeSet; private RoundRobinVolumeChoosingPolicy volumeChoosingPolicy; + private MinFreeSpaceCalculator freeSpaceCalculator; private KeyValueContainerData keyValueContainerData; private KeyValueContainer keyValueContainer; private final DatanodeDetails datanodeDetails = createDatanodeDetails(); @@ -99,6 +101,7 @@ private void setup() throws Exception { clusterId, conf, null, StorageVolume.VolumeType.DATA_VOLUME, null); createDbInstancesForTestIfNeeded(volumeSet, clusterId, clusterId, conf); volumeChoosingPolicy = new RoundRobinVolumeChoosingPolicy(); + freeSpaceCalculator = new MinFreeSpaceCalculator(conf); } @AfterEach @@ -139,7 +142,7 @@ public void testBuildContainerMap(ContainerTestVersionInfo versionInfo) containerDatas.add(keyValueContainerData); keyValueContainer = new KeyValueContainer( keyValueContainerData, conf); - keyValueContainer.create(volumeSet, volumeChoosingPolicy, clusterId); + keyValueContainer.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, clusterId); myVolume = keyValueContainer.getContainerData().getVolume(); freeBytes = addBlocks(keyValueContainer, 2, 3); @@ -243,7 +246,7 @@ public void testContainerCreateDiskFull(ContainerTestVersionInfo versionInfo) StorageContainerException e = assertThrows( StorageContainerException.class, () -> keyValueContainer. - create(volumeSet, volumeChoosingPolicy, clusterId) + create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, clusterId) ); assertEquals(DISK_OUT_OF_SPACE, e.getResult()); } diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/replication/TestGrpcReplicationService.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/replication/TestGrpcReplicationService.java index 9822c07068d5..3bd93c14e16c 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/replication/TestGrpcReplicationService.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/replication/TestGrpcReplicationService.java @@ -56,6 +56,7 @@ import org.apache.hadoop.ozone.container.common.volume.HddsVolume; import org.apache.hadoop.ozone.container.common.volume.MutableVolumeSet; import org.apache.hadoop.ozone.container.common.volume.RoundRobinVolumeChoosingPolicy; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainer; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData; import org.apache.hadoop.ozone.container.keyvalue.KeyValueHandler; @@ -143,7 +144,7 @@ public void init() throws Exception { StorageVolumeUtil.getHddsVolumesList(volumeSet.getVolumesList()) .forEach(hddsVolume -> hddsVolume.setDbParentDir(tempDir.toFile())); container.create(volumeSet, new RoundRobinVolumeChoosingPolicy(), - "test-replication"); + new MinFreeSpaceCalculator(conf), "test-replication"); containerSet.addContainer(container); container.close(); diff --git a/hadoop-hdds/tools/src/test/java/org/apache/hadoop/hdds/scm/cli/container/upgrade/TestUpgradeManager.java b/hadoop-hdds/tools/src/test/java/org/apache/hadoop/hdds/scm/cli/container/upgrade/TestUpgradeManager.java index 4d9501887678..eb01ba65f9f8 100644 --- a/hadoop-hdds/tools/src/test/java/org/apache/hadoop/hdds/scm/cli/container/upgrade/TestUpgradeManager.java +++ b/hadoop-hdds/tools/src/test/java/org/apache/hadoop/hdds/scm/cli/container/upgrade/TestUpgradeManager.java @@ -25,6 +25,7 @@ import static org.apache.hadoop.ozone.container.common.states.endpoint.VersionEndpointTask.LOG; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.anyList; import static org.mockito.Mockito.anyLong; import static org.mockito.Mockito.mock; @@ -60,6 +61,7 @@ import org.apache.hadoop.ozone.container.common.volume.MutableVolumeSet; import org.apache.hadoop.ozone.container.common.volume.RoundRobinVolumeChoosingPolicy; import org.apache.hadoop.ozone.container.common.volume.StorageVolume; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainer; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData; import org.apache.hadoop.ozone.container.keyvalue.impl.BlockManagerImpl; @@ -85,6 +87,7 @@ public class TestUpgradeManager { private MutableVolumeSet volumeSet; private UUID datanodeId; private RoundRobinVolumeChoosingPolicy volumeChoosingPolicy; + private MinFreeSpaceCalculator freeSpaceCalculator; private BlockManager blockManager; private FilePerBlockStrategy chunkManager; @@ -126,8 +129,9 @@ public void setup() throws Exception { when(datanodeDetails.getUuid()).thenReturn(datanodeId); volumeChoosingPolicy = mock(RoundRobinVolumeChoosingPolicy.class); + freeSpaceCalculator = mock(MinFreeSpaceCalculator.class); final AtomicInteger loopCount = new AtomicInteger(0); - when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong())) + when(volumeChoosingPolicy.chooseVolume(anyList(), anyLong(), any(MinFreeSpaceCalculator.class))) .thenAnswer(invocation -> { final int ii = loopCount.getAndIncrement() % volumes.size(); return volumes.get(ii); @@ -243,7 +247,7 @@ private void putChunksInBlock(int numOfChunksPerBlock, int i, data.setSchemaVersion(OzoneConsts.SCHEMA_V2); KeyValueContainer container = new KeyValueContainer(data, CONF); - container.create(volumeSet, volumeChoosingPolicy, SCM_ID); + container.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, SCM_ID); containerSet.addContainer(container); data = (KeyValueContainerData) containerSet.getContainer(containerId) diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/ChunkManagerDiskWrite.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/ChunkManagerDiskWrite.java index 0e0d174d061a..b639bf8f37a7 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/ChunkManagerDiskWrite.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/ChunkManagerDiskWrite.java @@ -41,6 +41,7 @@ import org.apache.hadoop.ozone.container.common.volume.RoundRobinVolumeChoosingPolicy; import org.apache.hadoop.ozone.container.common.volume.StorageVolume; import org.apache.hadoop.ozone.container.common.volume.VolumeSet; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainer; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData; import org.apache.hadoop.ozone.container.keyvalue.impl.ChunkManagerFactory; @@ -112,6 +113,7 @@ public Void call() throws Exception { VolumeChoosingPolicy volumeChoicePolicy = new RoundRobinVolumeChoosingPolicy(); + MinFreeSpaceCalculator freeSpaceCalculator = new MinFreeSpaceCalculator(ozoneConfiguration); final int threadCount = getThreadNo(); @@ -130,7 +132,7 @@ public Void call() throws Exception { KeyValueContainer keyValueContainer = new KeyValueContainer(keyValueContainerData, ozoneConfiguration); - keyValueContainer.create(volumeSet, volumeChoicePolicy, "scmid"); + keyValueContainer.create(volumeSet, volumeChoicePolicy, freeSpaceCalculator, "scmid"); containersPerThread.put(i, keyValueContainer); } diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/containergenerator/GeneratorDatanode.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/containergenerator/GeneratorDatanode.java index ef5d289b2205..d4be09a090b3 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/containergenerator/GeneratorDatanode.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/containergenerator/GeneratorDatanode.java @@ -56,6 +56,7 @@ import org.apache.hadoop.ozone.container.common.volume.MutableVolumeSet; import org.apache.hadoop.ozone.container.common.volume.RoundRobinVolumeChoosingPolicy; import org.apache.hadoop.ozone.container.common.volume.StorageVolume; +import org.apache.hadoop.ozone.container.common.volume.VolumeUsage.MinFreeSpaceCalculator; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainer; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData; import org.apache.hadoop.ozone.container.keyvalue.impl.BlockManagerImpl; @@ -114,6 +115,7 @@ public class GeneratorDatanode extends BaseGenerator { private BlockManagerImpl blockManager; private RoundRobinVolumeChoosingPolicy volumeChoosingPolicy; + private MinFreeSpaceCalculator freeSpaceCalculator; private MutableVolumeSet volumeSet; @@ -171,6 +173,7 @@ public Void call() throws Exception { StorageVolume.VolumeType.DATA_VOLUME, null); volumeChoosingPolicy = new RoundRobinVolumeChoosingPolicy(); + freeSpaceCalculator = new MinFreeSpaceCalculator(config); final OzoneClientConfig ozoneClientConfig = config.getObject(OzoneClientConfig.class); @@ -329,7 +332,7 @@ private KeyValueContainer createContainer(long containerId) new KeyValueContainer(keyValueContainerData, config); try { - keyValueContainer.create(volumeSet, volumeChoosingPolicy, scmId); + keyValueContainer.create(volumeSet, volumeChoosingPolicy, freeSpaceCalculator, scmId); } catch (StorageContainerException ex) { throw new RuntimeException(ex); }