You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ratis.apache.org by sz...@apache.org on 2021/06/10 06:37:12 UTC
[ratis] branch master updated: RATIS-1377. Ratis min free space for
storage dirs. (#479)
This is an automated email from the ASF dual-hosted git repository.
szetszwo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ratis.git
The following commit(s) were added to refs/heads/master by this push:
new a731551 RATIS-1377. Ratis min free space for storage dirs. (#479)
a731551 is described below
commit a7315511bddcc12dc4acea25f2d0d71608a8591c
Author: Gui Hecheng <ma...@tencent.com>
AuthorDate: Thu Jun 10 14:37:03 2021 +0800
RATIS-1377. Ratis min free space for storage dirs. (#479)
---
.../org/apache/ratis/server/RaftServerConfigKeys.java | 10 ++++++++++
.../org/apache/ratis/server/impl/ServerState.java | 3 ++-
.../server/storage/RaftStorageDirectoryImpl.java | 17 ++++++++++++++++-
.../apache/ratis/server/storage/RaftStorageImpl.java | 10 ++++++----
.../ratis/server/storage/RaftStorageTestUtils.java | 2 +-
.../apache/ratis/server/storage/TestRaftStorage.java | 19 +++++++++++++++----
6 files changed, 50 insertions(+), 11 deletions(-)
diff --git a/ratis-server-api/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java b/ratis-server-api/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java
index 7e888ff..892cc16 100644
--- a/ratis-server-api/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java
+++ b/ratis-server-api/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java
@@ -51,6 +51,16 @@ public interface RaftServerConfigKeys {
setFiles(properties::setFiles, STORAGE_DIR_KEY, storageDir);
}
+ String STORAGE_FREE_SPACE_MIN_KEY = PREFIX + ".storage.free-space.min";
+ SizeInBytes STORAGE_FREE_SPACE_MIN_DEFAULT = SizeInBytes.valueOf("0MB");
+ static SizeInBytes storageFreeSpaceMin(RaftProperties properties) {
+ return getSizeInBytes(properties::getSizeInBytes,
+ STORAGE_FREE_SPACE_MIN_KEY, STORAGE_FREE_SPACE_MIN_DEFAULT, getDefaultLog());
+ }
+ static void setStorageFreeSpaceMin(RaftProperties properties, SizeInBytes storageFreeSpaceMin) {
+ setSizeInBytes(properties::set, STORAGE_FREE_SPACE_MIN_KEY, storageFreeSpaceMin);
+ }
+
String REMOVED_GROUPS_DIR_KEY = PREFIX + ".removed.groups.dir";
File REMOVED_GROUPS_DIR_DEFAULT = new File("/tmp/raft-server/removed-groups/");
static File removedGroupsDir(RaftProperties properties) {
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java
index b5557c5..38a37a1 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java
@@ -110,7 +110,8 @@ class ServerState implements Closeable {
// use full uuid string to create a subdirectory
File dir = chooseStorageDir(directories, group.getGroupId().getUuid().toString());
try {
- storage = new RaftStorageImpl(dir, RaftServerConfigKeys.Log.corruptionPolicy(prop));
+ storage = new RaftStorageImpl(dir, RaftServerConfigKeys.Log.corruptionPolicy(prop),
+ RaftServerConfigKeys.storageFreeSpaceMin(prop).getSize());
storageFound = true;
break;
} catch (IOException e) {
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/storage/RaftStorageDirectoryImpl.java b/ratis-server/src/main/java/org/apache/ratis/server/storage/RaftStorageDirectoryImpl.java
index 5e69f7d..8647179 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/storage/RaftStorageDirectoryImpl.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/storage/RaftStorageDirectoryImpl.java
@@ -43,19 +43,22 @@ class RaftStorageDirectoryImpl implements RaftStorageDirectory {
enum StorageState {
NON_EXISTENT,
NOT_FORMATTED,
+ NO_SPACE,
NORMAL
}
private final File root; // root directory
private FileLock lock; // storage lock
+ private long freeSpaceMin;
/**
* Constructor
* @param dir directory corresponding to the storage
*/
- RaftStorageDirectoryImpl(File dir) {
+ RaftStorageDirectoryImpl(File dir, long freeSpaceMin) {
this.root = dir;
this.lock = null;
+ this.freeSpaceMin = freeSpaceMin;
}
@Override
@@ -150,6 +153,14 @@ class RaftStorageDirectoryImpl implements RaftStorageDirectory {
this.lock(); // lock storage if it exists
}
+ // check enough space
+ if (!hasEnoughSpace()) {
+ LOG.warn("There are not enough space left for directory " + rootPath
+ + " free space min required: " + freeSpaceMin
+ + " free space actual: " + root.getFreeSpace());
+ return StorageState.NO_SPACE;
+ }
+
// check whether current directory is valid
if (isHealthy()) {
return StorageState.NORMAL;
@@ -163,6 +174,10 @@ class RaftStorageDirectoryImpl implements RaftStorageDirectory {
return getMetaFile().exists();
}
+ private boolean hasEnoughSpace() {
+ return root.getFreeSpace() > freeSpaceMin;
+ }
+
/**
* Lock storage to provide exclusive access.
*
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/storage/RaftStorageImpl.java b/ratis-server/src/main/java/org/apache/ratis/server/storage/RaftStorageImpl.java
index 93772da..0bbf902 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/storage/RaftStorageImpl.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/storage/RaftStorageImpl.java
@@ -47,12 +47,14 @@ public class RaftStorageImpl implements RaftStorage {
private final CorruptionPolicy logCorruptionPolicy;
private volatile RaftStorageMetadataFileImpl metaFile;
- public RaftStorageImpl(File dir, CorruptionPolicy logCorruptionPolicy) throws IOException {
- this(dir, logCorruptionPolicy, null);
+ public RaftStorageImpl(File dir, CorruptionPolicy logCorruptionPolicy,
+ long storageFeeSpaceMin) throws IOException {
+ this(dir, logCorruptionPolicy, null, storageFeeSpaceMin);
}
- RaftStorageImpl(File dir, CorruptionPolicy logCorruptionPolicy, StartupOption option) throws IOException {
- this.storageDir = new RaftStorageDirectoryImpl(dir);
+ RaftStorageImpl(File dir, CorruptionPolicy logCorruptionPolicy, StartupOption option,
+ long storageFeeSpaceMin) throws IOException {
+ this.storageDir = new RaftStorageDirectoryImpl(dir, storageFeeSpaceMin);
if (option == StartupOption.FORMAT) {
if (storageDir.analyzeStorage(false) == StorageState.NON_EXISTENT) {
throw new IOException("Cannot format " + storageDir);
diff --git a/ratis-server/src/test/java/org/apache/ratis/server/storage/RaftStorageTestUtils.java b/ratis-server/src/test/java/org/apache/ratis/server/storage/RaftStorageTestUtils.java
index 9f192e4..d8c48ff 100644
--- a/ratis-server/src/test/java/org/apache/ratis/server/storage/RaftStorageTestUtils.java
+++ b/ratis-server/src/test/java/org/apache/ratis/server/storage/RaftStorageTestUtils.java
@@ -33,7 +33,7 @@ import java.util.function.Consumer;
public interface RaftStorageTestUtils {
static RaftStorage newRaftStorage(File dir) throws IOException {
- return new RaftStorageImpl(dir, null);
+ return new RaftStorageImpl(dir, null, 0L);
}
static String getLogFlushTimeMetric(String memberId) {
diff --git a/ratis-test/src/test/java/org/apache/ratis/server/storage/TestRaftStorage.java b/ratis-test/src/test/java/org/apache/ratis/server/storage/TestRaftStorage.java
index 678e432..89e2cce 100644
--- a/ratis-test/src/test/java/org/apache/ratis/server/storage/TestRaftStorage.java
+++ b/ratis-test/src/test/java/org/apache/ratis/server/storage/TestRaftStorage.java
@@ -31,6 +31,7 @@ import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.Mockito;
import java.io.File;
import java.io.IOException;
@@ -46,7 +47,7 @@ import java.util.regex.Matcher;
*/
public class TestRaftStorage extends BaseTest {
static RaftStorageImpl newRaftStorage(File dir) throws IOException {
- return new RaftStorageImpl(dir, null);
+ return new RaftStorageImpl(dir, null, 0);
}
private File storageDir;
@@ -64,7 +65,7 @@ public class TestRaftStorage extends BaseTest {
}
static RaftStorageImpl formatRaftStorage(File dir) throws IOException {
- return new RaftStorageImpl(dir, null, RaftStorageImpl.StartupOption.FORMAT);
+ return new RaftStorageImpl(dir, null, RaftStorageImpl.StartupOption.FORMAT, 0);
}
@Test
@@ -99,7 +100,7 @@ public class TestRaftStorage extends BaseTest {
*/
@Test
public void testStorage() throws Exception {
- final RaftStorageDirectoryImpl sd = new RaftStorageDirectoryImpl(storageDir);
+ final RaftStorageDirectoryImpl sd = new RaftStorageDirectoryImpl(storageDir, 0);
try {
StorageState state = sd.analyzeStorage(true);
Assert.assertEquals(StorageState.NOT_FORMATTED, state);
@@ -156,7 +157,7 @@ public class TestRaftStorage extends BaseTest {
Assert.assertEquals(StorageState.NORMAL, storage.getState());
storage.close();
- final RaftStorageDirectoryImpl sd = new RaftStorageDirectoryImpl(storageDir);
+ final RaftStorageDirectoryImpl sd = new RaftStorageDirectoryImpl(storageDir, 0);
File metaFile = sd.getMetaFile();
FileUtils.move(metaFile, sd.getMetaTmpFile());
@@ -265,4 +266,14 @@ public class TestRaftStorage extends BaseTest {
Assert.assertTrue(stateMachineDir.listFiles().length == 5);
}
+
+ @Test
+ public void testNotEnoughSpace() throws IOException {
+ File mockStorageDir = Mockito.spy(storageDir);
+ Mockito.when(mockStorageDir.getFreeSpace()).thenReturn(100L); // 100B
+
+ final RaftStorageDirectoryImpl sd = new RaftStorageDirectoryImpl(mockStorageDir, 104857600); // 100MB
+ StorageState state = sd.analyzeStorage(false);
+ Assert.assertEquals(StorageState.NO_SPACE, state);
+ }
}