use of org.apache.hadoop.ozone.container.common.statemachine.DatanodeConfiguration in project ozone by apache.
the class TestDeleteWithSlowFollower method init.
/**
* Create a MiniDFSCluster for testing.
*
* @throws IOException
*/
@BeforeClass
public static void init() throws Exception {
conf = new OzoneConfiguration();
path = GenericTestUtils.getTempPath(TestContainerStateMachineFailures.class.getSimpleName());
File baseDir = new File(path);
baseDir.mkdirs();
conf.setTimeDuration(HDDS_CONTAINER_REPORT_INTERVAL, 200, TimeUnit.MILLISECONDS);
conf.setInt(ScmConfigKeys.OZONE_DATANODE_PIPELINE_LIMIT, 1);
// Make the stale, dead and server failure timeout higher so that a dead
// node is not detecte at SCM as well as the pipeline close action
// never gets initiated early at Datanode in the test.
conf.setTimeDuration(HDDS_COMMAND_STATUS_REPORT_INTERVAL, 200, TimeUnit.MILLISECONDS);
conf.setTimeDuration(HDDS_SCM_WATCHER_TIMEOUT, 1000, TimeUnit.MILLISECONDS);
conf.setTimeDuration(OZONE_SCM_STALENODE_INTERVAL, 1000, TimeUnit.SECONDS);
conf.setTimeDuration(ScmConfigKeys.OZONE_SCM_DEADNODE_INTERVAL, 2000, TimeUnit.SECONDS);
conf.setTimeDuration(OZONE_SCM_PIPELINE_DESTROY_TIMEOUT, 1000, TimeUnit.SECONDS);
conf.setTimeDuration(OZONE_SCM_PIPELINE_CREATION_INTERVAL, 1000, TimeUnit.SECONDS);
DatanodeRatisServerConfig ratisServerConfig = conf.getObject(DatanodeRatisServerConfig.class);
ratisServerConfig.setFollowerSlownessTimeout(Duration.ofSeconds(1000));
ratisServerConfig.setNoLeaderTimeout(Duration.ofSeconds(1000));
ratisServerConfig.setRequestTimeOut(Duration.ofSeconds(3));
ratisServerConfig.setWatchTimeOut(Duration.ofSeconds(3));
conf.setFromObject(ratisServerConfig);
RatisClientConfig.RaftConfig raftClientConfig = conf.getObject(RatisClientConfig.RaftConfig.class);
raftClientConfig.setRpcRequestTimeout(Duration.ofSeconds(3));
raftClientConfig.setRpcWatchRequestTimeout(Duration.ofSeconds(10));
conf.setFromObject(raftClientConfig);
conf.setTimeDuration(OzoneConfigKeys.OZONE_BLOCK_DELETING_SERVICE_INTERVAL, 1, TimeUnit.SECONDS);
ScmConfig scmConfig = conf.getObject(ScmConfig.class);
scmConfig.setBlockDeletionInterval(Duration.ofSeconds(1));
conf.setFromObject(scmConfig);
DatanodeConfiguration datanodeConfiguration = conf.getObject(DatanodeConfiguration.class);
datanodeConfiguration.setBlockDeletionInterval(Duration.ofMillis(100));
conf.setFromObject(datanodeConfiguration);
RatisClientConfig ratisClientConfig = conf.getObject(RatisClientConfig.class);
ratisClientConfig.setWriteRequestTimeout(Duration.ofSeconds(30));
ratisClientConfig.setWatchRequestTimeout(Duration.ofSeconds(30));
conf.setFromObject(ratisClientConfig);
conf.setQuietMode(false);
int numOfDatanodes = 3;
cluster = MiniOzoneCluster.newBuilder(conf).setNumDatanodes(numOfDatanodes).setTotalPipelineNumLimit(numOfDatanodes + FACTOR_THREE_PIPELINE_COUNT).setHbInterval(100).build();
cluster.waitForClusterToBeReady();
cluster.waitForPipelineTobeReady(THREE, 60000);
// the easiest way to create an open container is creating a key
client = OzoneClientFactory.getRpcClient(conf);
objectStore = client.getObjectStore();
xceiverClientManager = new XceiverClientManager(conf);
volumeName = "testcontainerstatemachinefailures";
bucketName = volumeName;
objectStore.createVolume(volumeName);
objectStore.getVolume(volumeName).createBucket(bucketName);
}
use of org.apache.hadoop.ozone.container.common.statemachine.DatanodeConfiguration in project ozone by apache.
the class TestPeriodicVolumeChecker method testPeriodicVolumeChecker.
@Test
public void testPeriodicVolumeChecker() throws Exception {
LOG.info("Executing {}", testName.getMethodName());
DatanodeConfiguration dnConf = conf.getObject(DatanodeConfiguration.class);
Duration gap = dnConf.getDiskCheckMinGap();
Duration interval = Duration.ofMinutes(dnConf.getPeriodicDiskCheckIntervalMinutes());
FakeTimer timer = new FakeTimer();
StorageVolumeChecker volumeChecker = new StorageVolumeChecker(conf, timer);
try {
volumeChecker.registerVolumeSet(new ImmutableVolumeSet(makeVolumes(2, HEALTHY)));
volumeChecker.registerVolumeSet(new ImmutableVolumeSet(makeVolumes(1, HEALTHY)));
volumeChecker.setDelegateChecker(new TestStorageVolumeChecker.DummyChecker());
Assert.assertEquals(0, volumeChecker.getNumAllVolumeChecks());
Assert.assertEquals(0, volumeChecker.getNumAllVolumeSetsChecks());
// first round
timer.advance(gap.toMillis() / 3);
volumeChecker.checkAllVolumeSets();
Assert.assertEquals(2, volumeChecker.getNumAllVolumeChecks());
Assert.assertEquals(1, volumeChecker.getNumAllVolumeSetsChecks());
Assert.assertEquals(0, volumeChecker.getNumSkippedChecks());
// periodic disk checker next round within gap
timer.advance(gap.toMillis() / 3);
volumeChecker.checkAllVolumeSets();
// skipped next round
Assert.assertEquals(2, volumeChecker.getNumAllVolumeChecks());
Assert.assertEquals(1, volumeChecker.getNumAllVolumeSetsChecks());
Assert.assertEquals(1, volumeChecker.getNumSkippedChecks());
// periodic disk checker next round
timer.advance(interval.toMillis());
volumeChecker.checkAllVolumeSets();
Assert.assertEquals(4, volumeChecker.getNumAllVolumeChecks());
Assert.assertEquals(2, volumeChecker.getNumAllVolumeSetsChecks());
Assert.assertEquals(1, volumeChecker.getNumSkippedChecks());
} finally {
volumeChecker.shutdownAndWait(1, TimeUnit.SECONDS);
}
}
use of org.apache.hadoop.ozone.container.common.statemachine.DatanodeConfiguration in project ozone by apache.
the class TestBlockDeletingService method testBlockDeletion.
@Test
public void testBlockDeletion() throws Exception {
DatanodeConfiguration dnConf = conf.getObject(DatanodeConfiguration.class);
dnConf.setBlockDeletionLimit(2);
this.blockLimitPerInterval = dnConf.getBlockDeletionLimit();
conf.setFromObject(dnConf);
ContainerSet containerSet = new ContainerSet();
createToDeleteBlocks(containerSet, 1, 3, 1);
ContainerMetrics metrics = ContainerMetrics.create(conf);
KeyValueHandler keyValueHandler = new KeyValueHandler(conf, datanodeUuid, containerSet, volumeSet, metrics, c -> {
});
BlockDeletingServiceTestImpl svc = getBlockDeletingService(containerSet, conf, keyValueHandler);
svc.start();
GenericTestUtils.waitFor(svc::isStarted, 100, 3000);
// Ensure 1 container was created
List<ContainerData> containerData = Lists.newArrayList();
containerSet.listContainer(0L, 1, containerData);
KeyValueContainerData data = (KeyValueContainerData) containerData.get(0);
Assert.assertEquals(1, containerData.size());
try (ReferenceCountedDB meta = BlockUtils.getDB((KeyValueContainerData) containerData.get(0), conf)) {
Map<Long, Container<?>> containerMap = containerSet.getContainerMapCopy();
// NOTE: this test assumes that all the container is KetValueContainer and
// have DeleteTransactionId in KetValueContainerData. If other
// types is going to be added, this test should be checked.
long transactionId = ((KeyValueContainerData) containerMap.get(containerData.get(0).getContainerID()).getContainerData()).getDeleteTransactionId();
long containerSpace = containerData.get(0).getBytesUsed();
// Number of deleted blocks in container should be equal to 0 before
// block delete
Assert.assertEquals(0, transactionId);
// Ensure there are 3 blocks under deletion and 0 deleted blocks
Assert.assertEquals(3, getUnderDeletionBlocksCount(meta, data));
Assert.assertEquals(3, meta.getStore().getMetadataTable().get(OzoneConsts.PENDING_DELETE_BLOCK_COUNT).longValue());
// Container contains 3 blocks. So, space used by the container
// should be greater than zero.
Assert.assertTrue(containerSpace > 0);
// An interval will delete 1 * 2 blocks
deleteAndWait(svc, 1);
GenericTestUtils.waitFor(() -> containerData.get(0).getBytesUsed() == containerSpace / 3, 100, 3000);
// After first interval 2 blocks will be deleted. Hence, current space
// used by the container should be less than the space used by the
// container initially(before running deletion services).
Assert.assertTrue(containerData.get(0).getBytesUsed() < containerSpace);
deleteAndWait(svc, 2);
// After deletion of all 3 blocks, space used by the containers
// should be zero.
GenericTestUtils.waitFor(() -> containerData.get(0).getBytesUsed() == 0, 100, 3000);
// Check finally DB counters.
// Not checking bytes used, as handler is a mock call.
Assert.assertEquals(0, meta.getStore().getMetadataTable().get(OzoneConsts.PENDING_DELETE_BLOCK_COUNT).longValue());
Assert.assertEquals(0, meta.getStore().getMetadataTable().get(OzoneConsts.BLOCK_COUNT).longValue());
}
svc.shutdown();
}
use of org.apache.hadoop.ozone.container.common.statemachine.DatanodeConfiguration in project ozone by apache.
the class TestStorageVolumeChecker method testVolumeDeletion.
/**
* Test {@link StorageVolumeChecker#checkAllVolumes} propagates
* checks for all volumes to the delegate checker.
*
* @throws Exception
*/
@Test
public void testVolumeDeletion() throws Exception {
LOG.info("Executing {}", testName.getMethodName());
DatanodeConfiguration dnConf = conf.getObject(DatanodeConfiguration.class);
dnConf.setDiskCheckMinGap(Duration.ofMillis(0));
conf.setFromObject(dnConf);
DatanodeDetails datanodeDetails = ContainerTestUtils.createDatanodeDetails();
OzoneContainer ozoneContainer = ContainerTestUtils.getOzoneContainer(datanodeDetails, conf);
MutableVolumeSet volumeSet = ozoneContainer.getVolumeSet();
ContainerSet containerSet = ozoneContainer.getContainerSet();
StorageVolumeChecker volumeChecker = volumeSet.getVolumeChecker();
volumeChecker.setDelegateChecker(new DummyChecker());
File volParentDir = new File(folder.getRoot(), UUID.randomUUID().toString());
volumeSet.addVolume(volParentDir.getPath());
File volRootDir = new File(volParentDir, "hdds");
int i = 0;
for (ContainerDataProto.State state : ContainerDataProto.State.values()) {
if (!state.equals(ContainerDataProto.State.INVALID)) {
// add containers to the created volume
Container container = ContainerTestUtils.getContainer(++i, layout, state);
container.getContainerData().setVolume((HddsVolume) volumeSet.getVolumeMap().get(volRootDir.getPath()));
((KeyValueContainerData) container.getContainerData()).setMetadataPath(volParentDir.getPath());
containerSet.addContainer(container);
}
}
// delete the volume directory
FileUtils.deleteDirectory(volParentDir);
Assert.assertEquals(2, volumeSet.getVolumesList().size());
volumeSet.checkAllVolumes();
// failed volume should be removed from volumeSet volume list
Assert.assertEquals(1, volumeSet.getVolumesList().size());
Assert.assertEquals(1, volumeSet.getFailedVolumesList().size());
i = 0;
for (ContainerDataProto.State state : ContainerDataProto.State.values()) {
if (!state.equals(ContainerDataProto.State.INVALID)) {
Assert.assertEquals(ContainerDataProto.State.UNHEALTHY, containerSet.getContainer(++i).getContainerState());
}
}
ozoneContainer.stop();
}
use of org.apache.hadoop.ozone.container.common.statemachine.DatanodeConfiguration in project ozone by apache.
the class TestVolumeSetDiskChecks method getConfWithDataNodeDirs.
/**
* Update configuration with the specified number of Datanode
* storage directories.
* @param numDirs
*/
private OzoneConfiguration getConfWithDataNodeDirs(int numDirs) {
final OzoneConfiguration ozoneConf = new OzoneConfiguration();
final List<String> dirs = new ArrayList<>();
for (int i = 0; i < numDirs; ++i) {
dirs.add(GenericTestUtils.getRandomizedTestDir().getPath());
}
ozoneConf.set(DFSConfigKeysLegacy.DFS_DATANODE_DATA_DIR_KEY, String.join(",", dirs));
final List<String> metaDirs = new ArrayList<>();
for (int i = 0; i < numDirs; ++i) {
metaDirs.add(GenericTestUtils.getRandomizedTestDir().getPath());
}
ozoneConf.set(OzoneConfigKeys.DFS_CONTAINER_RATIS_DATANODE_STORAGE_DIR, String.join(",", metaDirs));
DatanodeConfiguration dnConf = ozoneConf.getObject(DatanodeConfiguration.class);
dnConf.setFailedDataVolumesTolerated(numDirs * 2);
dnConf.setFailedMetadataVolumesTolerated(numDirs * 2);
ozoneConf.setFromObject(dnConf);
return ozoneConf;
}
Aggregations