本篇文章作者對MinIO文章中的觀點提出質疑,該文章認為POSIX不適合用於物件儲存。他進行了全面的測試,涉及MinIO的s3fs-fuse
與JuiceFS。結果顯示,MinIO與JuiceFS表現出色,而s3fs-fuse
則有所滯後。在小檔案覆寫情境下,JuiceFS FUSE-POSIX的表現超越了其他解決方案。
最近,我在MinIO博客上讀到一篇名為”在物件儲存上建立檔案系統是個壞主意。以下是原因“的文章。作者以s3fs-fuse
為例,說明使用可攜式作業系統介面(POSIX)方法存取MinIO資料時遇到的效能挑戰,強調其效能遠落後於直接存取MinIO。作者將這些效能問題歸咎於POSIX固有的缺陷。然而,我們的經驗與此結論有所不同。
POSIX是一套實用且廣泛採用的標準。遵循POSIX開發的軟件能夠確保在不同操作系統間的兼容性和可移植性。各行各業中的大多數應用程序都遵循POSIX標準。隨著雲計算、大數據和AI技術的進步,以及存儲數據量的日益增加,對於像對象存儲這樣的彈性存儲解決方案的需求也在增長。儘管像MinIO這樣的對象存儲提供了多種語言的SDK,但許多傳統應用程序在將其代碼適配到使用對象存儲API時仍面臨困難。這導致了各種存儲產品在對象存儲之上實現POSIX接口以滿足這種不靈活的需求。
業界中有許多產品,如Ceph、JuiceFS和Weka,已成功在對象存儲上實現了POSIX接口。這些解決方案擁有龐大的用戶群和眾多成功案例,並在性能方面表現出色。
雖然POSIX確實具有相當的複雜性,但相關問題並非無法克服。出於對這些說法的尊重和驗證的願望,我搭建了一個測試環境,採用了與MinIO文章中相同的樣本數據和測試方法,進行了驗證。
產品比較與測試目標
為了提供全面的評估,我將JuiceFS引入比較中。
JuiceFS 是一個開源的雲原生分散式檔案系統,採用物件儲存作為資料儲存層,並依賴一個獨立的資料庫來儲存元資料。它提供了多種存取方式,包括 POSIX API、S3 API、CSI Driver、HDFS API 及 WebDAV,並具備獨特的資料區塊化、快取及並行讀寫機制。JuiceFS 是一個檔案系統,本質上與工具如s3fs-fuse
不同,後者僅將物件儲存轉換為 POSIX 協議。
引入 JuiceFS 進行比較,旨在客觀評估在物件儲存之上實現 POSIX 等協議的優缺點。
I conducted the following two tests on MinIO, JuiceFS, and s3fs-fuse
:
- 撰寫一個 10 GB 的檔案
- 使用 Pandas 覆蓋小檔案
三種解決方案均使用了部署在獨立伺服器上的 MinIO 實例作為底層儲存。測試樣本使用了一個 10 GB 的檔案,即 MinIO 文章中提到的相同CSV 檔案。
本文中的所有環境、軟體、腳本及樣本資料均附有完整的程式碼和指導,確保您能夠重現環境及測試結果。
伺服器及測試環境設定
兩台配置相同的雲端伺服器:
- 系統:Ubuntu 22.04 x64
- CPU:8 核心
- RAM:16 GB
- SSD:500 GB
- 網路:VPC
每台伺服器的資訊:
Server | IP | Purpose |
---|---|---|
Server A | 172.16.254.18 | Deploying the MinIO instance |
Server B | 172.16.254.19 | As the test environment |
伺服器 A 準備工作
1. 我使用Docker在Server A上部署了MinIO,执行了以下命令:
# 创建一个专用目录并导航至该目录。
mkdir minio && cd minio
# 创建配置文件。
mkdir config
touch config/minio
2. 我将以下信息写入到config/minio
文件中:
MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=abc123abc
MINIO_VOLUMES="/mnt/data"
3. 我创建了MinIO容器:
sudo docker run -d --name minio \
-p 9000:9000 \
-p 9090:9090 \
-v /mnt/minio-data:/mnt/data \
-v ./config/minio:/etc/config.env \
-e "MINIO_CONFIG_ENV_FILE=/etc/config.env" \
--restart unless-stopped \
minio/minio server --console-address ":9090"
4. 在MinIO的Web控制台中,我预先创建了三个存储桶:
Bucket name | Purpose |
---|---|
test-minio | For testing MinIO |
test-juicefs | For testing JuiceFS |
test-s3fs | For testing s3fs-fuse |
Server B准备工作
1. 我下载了10GB的测试样本文件。
curl -LO https://data.cityofnewyork.us/api/views/t29m-gskq/rows.csv?accessType=DOWNLOAD
2. 我安装了mc
客户端。
mc
是由MinIO项目开发的命令行文件管理器,它允许在Linux命令行中对本地和S3兼容的对象存储进行读写操作。mc cp
命令在数据复制过程中提供实时进度和速度更新,便于观察各种测试。
注意:为了保持测试的公平性,所有三种方法都使用
mc
进行文件写入测试。
# 下载mc。
wget https://dl.min.io/client/mc/release/linux-amd64/mc
# 检查mc版本。
mc -v
mc version RELEASE.2023-09-20T15-22-31Z (commit-id=38b8665e9e8649f98e6162bdb5163172e6ecc187)
Runtime: go1.21.1 linux/amd64
# 安装mc。
sudo install mc /usr/bin
# 为MinIO设置别名。
mc alias set my http://172.16.254.18:9000 admin abc123abc
3. 我下载了s3fs-fuse
。
sudo apt install s3fs
# 检查版本。
s3fs --version
Amazon Simple Storage Service File System V1.93 (commit:unknown) with OpenSSL
# 设置对象存储访问密钥。
echo admin:abc123abc > ~/.passwd-s3fs
# 修改密钥文件权限。
chmod 600 ~/.passwd-s3fs
# 创建挂载目录。
mkdir mnt-s3fs
# 挂载对象存储。
s3fs test-s3fs:/ /root/mnt-s3fs -o url=http://172.16.254.18:9000 -o use_path_request_style
4. 我安装了JuiceFS。
I used the official script to install the latest JuiceFS Community Edition.
# 一键安装脚本
curl -sSL https://d.juicefs.com/install | sh -
# 检查版本。
juicefs version
juicefs version 1.1.0+2023-09-04.08c4ae6
5. 我建立了一個文件系統。JuiceFS 是一種使用前需先建立的文件系統。除了對象存儲外,它還需要一個數據庫作為元數據引擎。它支援多種數據庫。在此,我使用了常用的Redis作為元數據引擎。
注意:我已在Server A上安裝了Redis,可通過
172.16.254.18:6379
無密碼訪問。安裝過程在此省略,詳情可參考Redis文檔。
# 建立文件系統。
juicefs format --storage minio \
--bucket http://172.16.254.18:9000/test-juicefs \
--access-key admin \
--secret-key abc123abc \
--trash-days 0 \
redis://172.16.254.18/1 \
myjfs
6. 我通過更常用的POSIX和S3 API方法訪問了JuiceFS,並測試了它們的性能。
# 創建掛載目錄。
mkdir ~/mnt-juicefs
# 以POSIX模式掛載文件系統。
juicefs mount redis://172.16.254.18/1 /root/mnt-juicefs
# 使用S3 API方法訪問文件系統。
export MINIO_ROOT_USER=admin
export MINIO_ROOT_PASSWORD=abc123abc
juicefs gateway redis://172.16.254.18/1 0.0.0.0:9000
# 在mc中為JuiceFS S3 API設置別名。
mc alias set juicefs http://172.16.254.18:9000 admin abc123abc
注意:JuiceFS Gateway也可部署在Server A或任何其他可通過互聯網訪問的服務器上,因為它提供了基於網絡的S3 API。
測試與結果
以下是我測試的快速總結與結果:
Test | MinIO | S3FS-FUSE | JuiceFS (FUSE) |
JuiceFS (S3 gateway) |
---|---|---|---|---|
Writing a 10 GB file | 0m27.651s | 3m6.380s | 0m28.107s | 0m28.091s |
Overwriting small files with Pandas | 0.83s | 0.78s | 0.46s | 0.96s |
測試1:寫入一個10GB文件
此測試旨在評估寫入大型文件的性能。所需時間越短,性能越好。我使用time
命令來測量寫操作的持續時間,提供了三個指標:
real
: 指令從開始到結束的實際時間,包含所有等待時間,如等待I/O操作完成、等待進程切換及資源等待。user
: 在用戶模式下執行的時間,表示用於執行用戶代碼的CPU時間,通常代表指令的計算工作負載。sys
: 在核心模式下執行的時間,表示用於執行核心代碼的CPU時間,通常代表與系統調用相關的工作負載,如文件I/O和進程管理。
MinIO
I ran the following command to perform a copy test:
time mc cp ./2018_Yellow_Taxi_Trip_Data.csv my/test-minio/
直接向MinIO寫入10GB文件的結果:
real 0m27.651s
user 0m10.767s
sys 0m5.439s
s3fs-fuse
I ran the following command to perform a copy test:
time mc cp ./2018_Yellow_Taxi_Trip_Data.csv /root/mnt-s3fs/
直接向s3fs-fuse
寫入10GB文件的結果:
real 3m6.380s
user 0m0.012s
sys 0m5.459s
注意:儘管
s3fs-fuse
的寫入時間為3分06秒,但並未出現MinIO文章中所描述的寫入失敗情況。
JuiceFS
I tested the performance of JuiceFS for large file writes using both the POSIX and S3 API methods:
# POSIX寫入測試
time mc cp ./2018_Yellow_Taxi_Trip_Data.csv /root/mnt-juicefs/
# S3 API寫入測試
time mc cp ./2018_Yellow_Taxi_Trip_Data.csv juicefs/myjfs/
JuiceFS POSIX寫入10GB文件的結果:
real 0m28.107s
user 0m0.292s
sys 0m6.930s
JuiceFS S3 API寫入10GB文件的結果:
real 0m28.091s
user 0m13.643s
sys 0m4.142s
大文件寫入結果總結
下圖顯示了測試結果:

測試結果顯示,無論是直接向MinIO還是JuiceFS寫入,兩者性能相當,均在約30秒內完成任務。相比之下,s3fs-fuse
寫入10GB文件耗時超過3分鐘,約為前兩者的六倍慢。
在處理大型檔案時,mc
利用Multipart API將檔案分塊上傳至S3介面。相反地,s3fs-fuse
僅能以單執行緒方式寫入POSIX。JuiceFS則會自動將大型檔案分割成塊,並在連續寫入時並行寫入MinIO,確保性能與直接寫入MinIO相當。而S3FS則是先以單執行緒方式寫入快取磁碟,然後再將檔案分塊上傳至MinIO,導致寫入時間較長。
根據計算,寫入一個10GB的檔案耗時30秒,平均速度為333MB/s。這受到雲端伺服器SSD頻寬的限制。這些測試結果表明,無論是MinIO還是JuiceFS都能充分利用本地SSD頻寬,且隨著伺服器雲端硬碟和網路頻寬的提升,其性能也將提升。
測試2:使用Pandas覆蓋小檔案
本測試評估了物件儲存系統在小檔案覆蓋情境下的性能。每個軟體的測試腳本略有不同。您可以在此處找到所有腳本代碼。
MinIO
I got the test script and ran the test:
# 獲取測試腳本。
curl -LO https://gist.githubusercontent.com/yuhr123/7acb7e6bb42fb0ff12f3ba64d2cdd7da/raw/30c748e20b56dec642a58f9cccd7ea6e213dab3c/pandas-minio.py
# 運行測試。
python3 pandas-minio.py
結果如下:
Execution time: 0.83 seconds
s3fs-fuse
I got the test script and ran the test:
# 獲取測試腳本。
curl -LO gist.githubusercontent.com/yuhr123/7acb7e6bb42fb0ff12f3ba64d2cdd7da/raw/30c748e20b56dec642a58f9cccd7ea6e213dab3c/pandas-s3fs.py
# 運行測試。
python3 pandas-s3fs.py
測試結果如下:
Execution time: 0.78 seconds
JuiceFS POSIX
I got the test script and ran the test:
# 獲取測試腳本。
curl -LO gist.githubusercontent.com/yuhr123/7acb7e6bb42fb0ff12f3ba64d2cdd7da/raw/30c748e20b56dec642a58f9cccd7ea6e213dab3c/pandas-juicefs-posix.py
# 運行測試。
python3 pandas-juicefs-posix.py
測試結果如下:
Execution time: 0.43 seconds
JuiceFS S3 API
I got the test script and ran the test:
# 獲取測試腳本。
curl -LO https://gist.githubusercontent.com/yuhr123/7acb7e6bb42fb0ff12f3ba64d2cdd7da/raw/30c748e20b56dec642a58f9cccd7ea6e213dab3c/pandas-juicefs-s3api.py
# 運行測試。
python3 pandas-juicefs-s3api.py
測試結果如下:
Execution time: 0.86 seconds
Pandas小文件覆寫總結
下圖顯示了測試結果:

在此測試中,JuiceFS FUSE-POSIX展現了最快的速度,幾乎是其他解決方案的兩倍。MinIO、s3fs-fuse
和JuiceFS S3 Gateway表現相近。從小文件覆寫的角度來看,POSIX接口證明更為高效,性能優於對象存儲接口。
問題與分析
問題1:為何S3FS如此緩慢?
分析:從測試數據來看,當寫入相同的10GB文件時,S3FS耗時3分鐘,而MinIO和JuiceFS均在約30秒內完成任務。這一顯著的性能差異主要源於不同的技術實現。當s3fs-fuse
寫入文件時,它首先將文件寫入本地臨時文件,然後以塊的形式上傳到對象存儲。如果本地磁盤空間不足,它會同步上傳。這需要在本機磁盤和S3存儲之間複製數據。因此,大文件或大量文件會導致性能下降。
此外,S3FS依賴於底層對象存儲的元數據管理能力。當處理大量文件時,頻繁與對象存儲交互以檢索元數據對性能影響顯著。簡而言之,寫入S3FS的文件大小和總量越大,相應的性能開銷也越大。
問題二:為何JuiceFS更快?
分析:在測試中,JuiceFS和S3FS均通過FUSE進行讀寫操作。JuiceFS充分利用了磁盤帶寬,類似於MinIO,但未遭遇S3FS那樣的性能問題。
答案在於它們各自的技術架構。在文件寫入過程中,數據經由FUSE層處理時,JuiceFS採用高並發、緩存和數據分塊技術,以減少FUSE層與底層對象存儲之間的通信開銷。這使得JuiceFS能同時處理更多文件的讀寫請求,降低等待時間和傳輸延遲。
另外,JuiceFS使用專用數據庫(在此例中為Redis)管理元數據。面對大量文件時,獨立的元數據引擎能有效減輕負載,加快文件定位速度。
結論
上述測試表明,以物件儲存為基礎並在其上實現POSIX介面,並不一定會導致性能損失。無論是寫入大型還是小型檔案,JuiceFS展現出的性能與直接使用MinIO寫入相當,且不會因POSIX存取而降低底層物件儲存的性能。此外,在Pandas表格覆寫方面,JuiceFS FUSE-POSIX的性能保持一致,甚至將近是MinIO的兩倍。
測試結果顯示,某些軟體如s3fs-fuse
在S3 API與POSIX介面之間轉換時可能會遇到性能下降。雖然它對於暫時性的S3存取是一個便利的工具,但對於穩定且高性能的長期使用,需要仔細研究和驗證以選擇更合適的解決方案。
對於簡單的非結構化檔案歸檔,直接使用MinIO或雲端物件儲存是一個好選擇。然而,在涉及大規模資料儲存與處理的場景,如AI模型訓練、大數據分析、Kubernetes資料持久化及其他頻繁的讀寫操作,JuiceFS獨立的元資料管理、並發讀寫能力及快取機制提供了卓越的性能。它是一個值得考慮的高性能檔案系統解決方案。
Source:
https://dzone.com/articles/is-posix-really-unsuitable-for-object-stores-a-dat