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

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


The following commit(s) were added to refs/heads/master by this push:
     new ce06d0c97 [fs] HadoopFileIO should cache FileSystem by scheme and 
authority (#2504)
ce06d0c97 is described below

commit ce06d0c978db70ff469f525e3a3c6bf3708eb1d9
Author: Jingsong Lee <[email protected]>
AuthorDate: Wed Dec 13 18:21:29 2023 +0800

    [fs] HadoopFileIO should cache FileSystem by scheme and authority (#2504)
---
 .../org/apache/paimon/fs/hadoop/HadoopFileIO.java  | 38 ++++++++++++++++++----
 .../paimon/fs/HadoopLocalFileIOBehaviorTest.java   |  2 +-
 .../org/apache/paimon/fs/HdfsBehaviorTest.java     |  4 +--
 .../apache/paimon/oss/HadoopCompliantFileIO.java   |  3 ++
 .../apache/paimon/s3/HadoopCompliantFileIO.java    | 22 ++++++++++---
 5 files changed, 56 insertions(+), 13 deletions(-)

diff --git 
a/paimon-common/src/main/java/org/apache/paimon/fs/hadoop/HadoopFileIO.java 
b/paimon-common/src/main/java/org/apache/paimon/fs/hadoop/HadoopFileIO.java
index 7074341a7..70325ee69 100644
--- a/paimon-common/src/main/java/org/apache/paimon/fs/hadoop/HadoopFileIO.java
+++ b/paimon-common/src/main/java/org/apache/paimon/fs/hadoop/HadoopFileIO.java
@@ -26,6 +26,8 @@ import org.apache.paimon.fs.Path;
 import org.apache.paimon.fs.PositionOutputStream;
 import org.apache.paimon.fs.SeekableInputStream;
 import org.apache.paimon.hadoop.SerializableConfiguration;
+import org.apache.paimon.utils.FunctionWithException;
+import org.apache.paimon.utils.Pair;
 import org.apache.paimon.utils.ReflectionUtils;
 
 import org.apache.hadoop.fs.FSDataInputStream;
@@ -37,7 +39,10 @@ import java.io.IOException;
 import java.io.OutputStreamWriter;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.net.URI;
 import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicReference;
 
 /** Hadoop {@link FileIO}. */
@@ -47,11 +52,12 @@ public class HadoopFileIO implements FileIO {
 
     protected SerializableConfiguration hadoopConf;
 
-    protected transient volatile FileSystem fs;
+    protected transient volatile Map<Pair<String, String>, FileSystem> fsMap;
 
     @VisibleForTesting
-    public void setFileSystem(FileSystem fs) {
-        this.fs = fs;
+    public void setFileSystem(Path path, FileSystem fs) throws IOException {
+        org.apache.hadoop.fs.Path hadoopPath = path(path);
+        getFileSystem(hadoopPath, p -> fs);
     }
 
     @Override
@@ -136,13 +142,32 @@ public class HadoopFileIO implements FileIO {
     }
 
     private FileSystem getFileSystem(org.apache.hadoop.fs.Path path) throws 
IOException {
-        if (fs == null) {
+        return getFileSystem(path, this::createFileSystem);
+    }
+
+    private FileSystem getFileSystem(
+            org.apache.hadoop.fs.Path path,
+            FunctionWithException<org.apache.hadoop.fs.Path, FileSystem, 
IOException> creator)
+            throws IOException {
+        if (fsMap == null) {
             synchronized (this) {
-                if (fs == null) {
-                    fs = createFileSystem(path);
+                if (fsMap == null) {
+                    fsMap = new ConcurrentHashMap<>();
                 }
             }
         }
+
+        Map<Pair<String, String>, FileSystem> map = fsMap;
+
+        URI uri = path.toUri();
+        String scheme = uri.getScheme();
+        String authority = uri.getAuthority();
+        Pair<String, String> key = Pair.of(scheme, authority);
+        FileSystem fs = map.get(key);
+        if (fs == null) {
+            fs = creator.apply(path);
+            map.put(key, fs);
+        }
         return fs;
     }
 
@@ -373,6 +398,7 @@ public class HadoopFileIO implements FileIO {
                     new org.apache.hadoop.fs.Path(
                             path.getParent(), String.format(".%s.crc", 
path.getName()));
 
+            FileSystem fs = getFileSystem(checksumFile);
             if (fs.exists(checksumFile)) {
                 // checksum file exists, deleting it
                 fs.delete(checksumFile, true); // recursive=true
diff --git 
a/paimon-common/src/test/java/org/apache/paimon/fs/HadoopLocalFileIOBehaviorTest.java
 
b/paimon-common/src/test/java/org/apache/paimon/fs/HadoopLocalFileIOBehaviorTest.java
index 57a9aba7f..df94dd2a8 100644
--- 
a/paimon-common/src/test/java/org/apache/paimon/fs/HadoopLocalFileIOBehaviorTest.java
+++ 
b/paimon-common/src/test/java/org/apache/paimon/fs/HadoopLocalFileIOBehaviorTest.java
@@ -39,7 +39,7 @@ class HadoopLocalFileIOBehaviorTest extends 
FileIOBehaviorTestBase {
         org.apache.hadoop.fs.FileSystem fs = new RawLocalFileSystem();
         fs.initialize(URI.create("file:///"), new Configuration());
         HadoopFileIO fileIO = new HadoopFileIO();
-        fileIO.setFileSystem(fs);
+        fileIO.setFileSystem(getBasePath(), fs);
         return fileIO;
     }
 
diff --git 
a/paimon-common/src/test/java/org/apache/paimon/fs/HdfsBehaviorTest.java 
b/paimon-common/src/test/java/org/apache/paimon/fs/HdfsBehaviorTest.java
index df5eb7ba7..56bfe052e 100644
--- a/paimon-common/src/test/java/org/apache/paimon/fs/HdfsBehaviorTest.java
+++ b/paimon-common/src/test/java/org/apache/paimon/fs/HdfsBehaviorTest.java
@@ -60,10 +60,10 @@ class HdfsBehaviorTest extends FileIOBehaviorTestBase {
         hdfsCluster = builder.build();
 
         org.apache.hadoop.fs.FileSystem hdfs = hdfsCluster.getFileSystem();
-        fs = new HadoopFileIO();
-        fs.setFileSystem(hdfs);
 
         basePath = new Path(hdfs.getUri().toString() + "/tests");
+        fs = new HadoopFileIO();
+        fs.setFileSystem(basePath, hdfs);
     }
 
     @AfterAll
diff --git 
a/paimon-filesystems/paimon-oss-impl/src/main/java/org/apache/paimon/oss/HadoopCompliantFileIO.java
 
b/paimon-filesystems/paimon-oss-impl/src/main/java/org/apache/paimon/oss/HadoopCompliantFileIO.java
index 3f40c577a..4d86c12a6 100644
--- 
a/paimon-filesystems/paimon-oss-impl/src/main/java/org/apache/paimon/oss/HadoopCompliantFileIO.java
+++ 
b/paimon-filesystems/paimon-oss-impl/src/main/java/org/apache/paimon/oss/HadoopCompliantFileIO.java
@@ -118,6 +118,9 @@ public abstract class HadoopCompliantFileIO implements 
FileIO {
         Map<String, FileSystem> map = fsMap;
 
         String authority = path.toUri().getAuthority();
+        if (authority == null) {
+            authority = "DEFAULT";
+        }
         FileSystem fs = map.get(authority);
         if (fs == null) {
             fs = createFileSystem(path);
diff --git 
a/paimon-filesystems/paimon-s3-impl/src/main/java/org/apache/paimon/s3/HadoopCompliantFileIO.java
 
b/paimon-filesystems/paimon-s3-impl/src/main/java/org/apache/paimon/s3/HadoopCompliantFileIO.java
index fe86aca96..abfe0fabb 100644
--- 
a/paimon-filesystems/paimon-s3-impl/src/main/java/org/apache/paimon/s3/HadoopCompliantFileIO.java
+++ 
b/paimon-filesystems/paimon-s3-impl/src/main/java/org/apache/paimon/s3/HadoopCompliantFileIO.java
@@ -29,6 +29,8 @@ import org.apache.hadoop.fs.FSDataOutputStream;
 import org.apache.hadoop.fs.FileSystem;
 
 import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * Hadoop {@link FileIO}.
@@ -39,7 +41,7 @@ public abstract class HadoopCompliantFileIO implements FileIO 
{
 
     private static final long serialVersionUID = 1L;
 
-    protected transient volatile FileSystem fs;
+    protected transient volatile Map<String, FileSystem> fsMap;
 
     @Override
     public SeekableInputStream newInputStream(Path path) throws IOException {
@@ -105,13 +107,25 @@ public abstract class HadoopCompliantFileIO implements 
FileIO {
     }
 
     private FileSystem getFileSystem(org.apache.hadoop.fs.Path path) throws 
IOException {
-        if (fs == null) {
+        if (fsMap == null) {
             synchronized (this) {
-                if (fs == null) {
-                    fs = createFileSystem(path);
+                if (fsMap == null) {
+                    fsMap = new ConcurrentHashMap<>();
                 }
             }
         }
+
+        Map<String, FileSystem> map = fsMap;
+
+        String authority = path.toUri().getAuthority();
+        if (authority == null) {
+            authority = "DEFAULT";
+        }
+        FileSystem fs = map.get(authority);
+        if (fs == null) {
+            fs = createFileSystem(path);
+            map.put(authority, fs);
+        }
         return fs;
     }
 

Reply via email to