This is an automated email from the ASF dual-hosted git repository.

runzhiwang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-ratis.git


The following commit(s) were added to refs/heads/master by this push:
     new eb3aef5  RATIS-1228. FileStore support multi disk (#346)
eb3aef5 is described below

commit eb3aef5fdc4f8674cec3fb8f8eacfe4040fe883f
Author: runzhiwang <[email protected]>
AuthorDate: Thu Dec 10 10:58:27 2020 +0800

    RATIS-1228. FileStore support multi disk (#346)
---
 .../apache/ratis/examples/filestore/FileStore.java | 29 ++++++++++++++++------
 .../examples/filestore/FileStoreStateMachine.java  | 13 +++++++---
 .../ratis/examples/filestore/cli/Server.java       | 12 +++++----
 3 files changed, 38 insertions(+), 16 deletions(-)

diff --git 
a/ratis-examples/src/main/java/org/apache/ratis/examples/filestore/FileStore.java
 
b/ratis-examples/src/main/java/org/apache/ratis/examples/filestore/FileStore.java
index 8896462..c0af78e 100644
--- 
a/ratis-examples/src/main/java/org/apache/ratis/examples/filestore/FileStore.java
+++ 
b/ratis-examples/src/main/java/org/apache/ratis/examples/filestore/FileStore.java
@@ -36,12 +36,15 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.Closeable;
+import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.RandomAccessFile;
 import java.nio.ByteBuffer;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.CompletableFuture;
@@ -95,7 +98,7 @@ public class FileStore implements Closeable {
   }
 
   private final Supplier<RaftPeerId> idSupplier;
-  private final Supplier<Path> rootSupplier;
+  private final List<Supplier<Path>> rootSuppliers;
   private final FileMap files;
 
   private final ExecutorService writer = Executors.newFixedThreadPool(10);
@@ -103,10 +106,13 @@ public class FileStore implements Closeable {
   private final ExecutorService reader = Executors.newFixedThreadPool(10);
   private final ExecutorService deleter = Executors.newFixedThreadPool(3);
 
-  public FileStore(Supplier<RaftPeerId> idSupplier, Path dir) {
+  public FileStore(Supplier<RaftPeerId> idSupplier, List<File> dirs) {
     this.idSupplier = idSupplier;
-    this.rootSupplier = JavaUtils.memoize(
-        () -> dir.resolve(getId().toString()).normalize().toAbsolutePath());
+    this.rootSuppliers = new ArrayList<>();
+    for (File dir : dirs) {
+      this.rootSuppliers.add(
+          JavaUtils.memoize(() -> 
dir.toPath().resolve(getId().toString()).normalize().toAbsolutePath()));
+    }
     this.files = new FileMap(JavaUtils.memoize(() -> idSupplier.get() + 
":files"));
   }
 
@@ -115,8 +121,17 @@ public class FileStore implements Closeable {
         () -> JavaUtils.getClassSimpleName(getClass()) + " is not 
initialized.");
   }
 
-  public Path getRoot() {
-    return rootSupplier.get();
+  private Path getRoot(Path relative) {
+    int hash = relative.toAbsolutePath().toString().hashCode() % 
rootSuppliers.size();
+    return rootSuppliers.get(Math.abs(hash)).get();
+  }
+
+  public List<Path> getRoots() {
+    List<Path> roots = new ArrayList<>();
+    for (Supplier<Path> s : rootSuppliers) {
+      roots.add(s.get());
+    }
+    return roots;
   }
 
   static Path normalize(String path) {
@@ -125,7 +140,7 @@ public class FileStore implements Closeable {
   }
 
   Path resolve(Path relative) throws IOException {
-    final Path root = getRoot();
+    final Path root = getRoot(relative);
     final Path full = root.resolve(relative).normalize().toAbsolutePath();
     if (full.equals(root)) {
       throw new IOException("The file path " + relative + " resolved to " + 
full
diff --git 
a/ratis-examples/src/main/java/org/apache/ratis/examples/filestore/FileStoreStateMachine.java
 
b/ratis-examples/src/main/java/org/apache/ratis/examples/filestore/FileStoreStateMachine.java
index 0dc1561..65833e0 100644
--- 
a/ratis-examples/src/main/java/org/apache/ratis/examples/filestore/FileStoreStateMachine.java
+++ 
b/ratis-examples/src/main/java/org/apache/ratis/examples/filestore/FileStoreStateMachine.java
@@ -44,6 +44,8 @@ import org.apache.ratis.util.FileUtils;
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.Path;
+import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.CompletableFuture;
 
@@ -53,9 +55,10 @@ public class FileStoreStateMachine extends BaseStateMachine {
   private final FileStore files;
 
   public FileStoreStateMachine(RaftProperties properties) {
-    final File dir = ConfUtils.getFile(properties::getFile, 
FileStoreCommon.STATEMACHINE_DIR_KEY, null, LOG::info);
-    Objects.requireNonNull(dir, FileStoreCommon.STATEMACHINE_DIR_KEY + " is 
not set.");
-    this.files = new FileStore(this::getId, dir.toPath());
+    final List<File> dirs = ConfUtils.getFiles(properties::getFiles, 
FileStoreCommon.STATEMACHINE_DIR_KEY,
+        null, LOG::info);
+    Objects.requireNonNull(dirs, FileStoreCommon.STATEMACHINE_DIR_KEY + " is 
not set.");
+    this.files = new FileStore(this::getId, dirs);
   }
 
   @Override
@@ -63,7 +66,9 @@ public class FileStoreStateMachine extends BaseStateMachine {
       throws IOException {
     super.initialize(server, groupId, raftStorage);
     this.storage.init(raftStorage);
-    FileUtils.createDirectories(files.getRoot());
+    for (Path path : files.getRoots()) {
+      FileUtils.createDirectories(path);
+    }
   }
 
   @Override
diff --git 
a/ratis-examples/src/main/java/org/apache/ratis/examples/filestore/cli/Server.java
 
b/ratis-examples/src/main/java/org/apache/ratis/examples/filestore/cli/Server.java
index ac29d96..2ab348b 100644
--- 
a/ratis-examples/src/main/java/org/apache/ratis/examples/filestore/cli/Server.java
+++ 
b/ratis-examples/src/main/java/org/apache/ratis/examples/filestore/cli/Server.java
@@ -43,8 +43,9 @@ import org.apache.ratis.util.SizeInBytes;
 import org.apache.ratis.util.TimeDuration;
 
 import java.io.File;
+import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
+import java.util.List;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
@@ -57,8 +58,9 @@ public class Server extends SubCommandBase {
   @Parameter(names = {"--id", "-i"}, description = "Raft id of this server", 
required = true)
   private String id;
 
-  @Parameter(names = {"--storage", "-s"}, description = "Storage dir", 
required = true)
-  private File storageDir;
+  @Parameter(names = {"--storage", "-s"}, description = "Storage dir, eg. 
--storage dir1 --storage dir2",
+      required = true)
+  private List<File> storageDir = new ArrayList<>();
 
   @Override
   public void run() throws Exception {
@@ -77,10 +79,10 @@ public class Server extends SubCommandBase {
     NettyConfigKeys.DataStream.setPort(properties, dataStreamport);
     RaftConfigKeys.DataStream.setType(properties, 
SupportedDataStreamType.NETTY);
     properties.setInt(GrpcConfigKeys.OutputStream.RETRY_TIMES_KEY, 
Integer.MAX_VALUE);
-    RaftServerConfigKeys.setStorageDir(properties, 
Collections.singletonList(storageDir));
+    RaftServerConfigKeys.setStorageDir(properties, storageDir);
     RaftServerConfigKeys.Write.setElementLimit(properties, 40960);
     RaftServerConfigKeys.Write.setByteLimit(properties, 
SizeInBytes.valueOf("1000MB"));
-    ConfUtils.setFile(properties::setFile, 
FileStoreCommon.STATEMACHINE_DIR_KEY,
+    ConfUtils.setFiles(properties::setFiles, 
FileStoreCommon.STATEMACHINE_DIR_KEY,
         storageDir);
     StateMachine stateMachine = new FileStoreStateMachine(properties);
 

Reply via email to