You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ratis.apache.org by ru...@apache.org on 2020/12/10 02:58:36 UTC

[incubator-ratis] branch master updated: RATIS-1228. FileStore support multi disk (#346)

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 <51...@users.noreply.github.com>
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);