s3fs-fuse
是一個采用 c++🚀
開發的開源應用,它的作用是可以將 AWS S3
以及兼容 S3 API
的第三方對象存儲像普通文件系統一樣掛載到本地計算機,由於這種功能通過 FUSE
實現,因此只能在 Linux 和 MacOS 上使用。
安裝
配置
- 准備密碼文件
S3 及兼容 API 的對象存儲都采用 ACCESS KEY
和 ACCESS SECRET
認證身份,為了方便配置,可以將認證 KEY 放到獨立的密碼文件中,s3fs
默認會從以下兩個文件中讀取認證信息:
- 用戶家目錄下的
.passwd-s3fs
文件 (例如~/.passwd-s3fs
) - 全局文件
/etc/passwd-s3fs
任選其一即可,文件默認不存在,需要自己手動創建。
$ echo ACCESS_KEY_ID:SECRET_ACCESS_KEY > ~/.passwd-s3fs
$ chmod 600 ~/.passwd-s3fs
- 掛載 AWS S3
$ s3fs mybucket /path/to/mountpoint -o passwd_file=~/.passwd-s3fs
mybucket
替換成實際的 S3 Bucket/path/to/mountpoint
替換成本地掛載點-o
用來指定額外的參數,除非密碼文件沒有放在默認位置,否則不需指定密碼文件。
- 掛載兼容 S3 API 的第三方對象存儲
用 -o
指定對象存儲 Endpoint 地址即可,阿里雲OSS Endpoint地址參考這里🌐,七牛對象存儲 Endpoint地址參考這里🌐。
$ s3fs mybucket /path/to/mountpoint -o url=https://endpoint -o use_path_request_style
use_path_request_style
參數是對還不支持virtual-host
請求風格的對象存儲而提供的參數,指定該參數會使用傳統的 API 調用風格。實測表明,阿里雲 OSS 和七牛對象存儲不需指定該參數。
- 開機自動掛載
編輯 /etc/fstab
:
- For S3
s3fs#mybucket /path/to/mountpoint fuse _netdev,allow_other 0 0
- For S3-like
s3fs#mybucket /path/to/mountpoint fuse _netdev,allow_other,use_path_request_style,url=http://endpoint/ 0 0
注意:設置開機自動掛載可能需要把
s3fs
二進制文件放到/usr/local/bin
目錄,還要使用全局配置文件/etc/passwd-s3fs
保存密碼。
- 其他參數
- use_cache 使用緩存
設置 use_cache
將本地計算機的某個位置作為緩存,從而提高數據上傳的效率。
$ s3fs mybucket /path/to/mountpoint -o url=https://endpoint -o use_cache=/tmp
經過測試,普通盤的緩存可能還會降低吞吐,最好用機械盤,並做對比測試。
- del_cache 刪除緩存
指定 del_cache
參數,當 s3fs 啟動和退出時會自動刪除緩存文件。
性能優化
s3fs <bucket_name> <mountpoint> -o url=http://endpoint –o passwd_file=<credentials_file> \
-o cipher_suites=AESGCM \
-o kernel_cache \
-o max_background=1000 \
-o max_stat_cache_size=100000 \
-o multipart_size=64 \
-o parallel_count=30 \
-o multireq_max=30 \
-o dbglevel=warn
普通用戶命令行掛載s3fs
增加以下選項,並以管理員權限執行掛載命令
-o allow_other \
-o uid=1000 \
-o gid=1000 \
-o mp_umask=022 \
如果是/etc/fstab
文件,增加相應的選項即可。
測試
環境信息:
- Ubuntu 18
- 48核(Intel(R) Xeon(R) CPU E5-2678 v3 @ 2.50GHz)
- 128G
測試腳本
#!/bin/bash
BUCKET="testabc2"
MOUNT_POINT="/testabc2"
ENDPOINT=http://s3.test.com
parallel_counts=(10 20 30 40)
multipart_sizes=(10 16 32 64 128)
for parallel_count in ${parallel_counts[@]}; do
for multipart_size in ${multipart_sizes[@]}; do
echo "parallel_count: $parallel_count | multipart_size: $multipart_size"
# mount
/usr/local/bin/s3fs $BUCKET $MOUNT_POINT -o passwd_file=/root/.passwd-s3fs -o url=$ENDPOINT \
-o use_path_request_style \
-o parallel_count=${parallel_count} \
-o multipart_size=${multipart_size} \
-o max_background=1000 \
-o max_stat_cache_size=100000 \
-o multireq_max=30
sleep 1
# pv copy
dd if=/dev/zero of=${MOUNT_POINT}/2G.${RANDOM} bs=1M count=32 status=progress
sleep 1
# umount
umount ${MOUNT_POINT}
sleep 1
done
done
測試結果
並發數 | 分片大小 吞吐
parallel_count: 10 | multipart_size: 10 73.6 MB/s
parallel_count: 10 | multipart_size: 16 110 MB/s
parallel_count: 10 | multipart_size: 32 108 MB/s
parallel_count: 10 | multipart_size: 64 99.9 MB/s
parallel_count: 10 | multipart_size: 128 102 MB/s
parallel_count: 20 | multipart_size: 10 74.2 MB/s
parallel_count: 20 | multipart_size: 16 106 MB/s
parallel_count: 20 | multipart_size: 32 108 MB/s
parallel_count: 20 | multipart_size: 64 105 MB/s
parallel_count: 20 | multipart_size: 128 100 MB/s
parallel_count: 30 | multipart_size: 10 77.2 MB/s
parallel_count: 30 | multipart_size: 16 107 MB/s
parallel_count: 30 | multipart_size: 32 105 MB/s
parallel_count: 30 | multipart_size: 64 102 MB/s
parallel_count: 30 | multipart_size: 128 112 MB/s
parallel_count: 40 | multipart_size: 10 73.0 MB/s
parallel_count: 40 | multipart_size: 16 109 MB/s
parallel_count: 40 | multipart_size: 32 104 MB/s
parallel_count: 40 | multipart_size: 64 102 MB/s
parallel_count: 40 | multipart_size: 128 108 MB/s
結果分析
parallel_count
對吞吐的影響不大,multipart_size
對吞吐影響較大,因此采用這組數據parallel_count: 10 | multipart_size: 16 110 MB/s
。
使用記錄
- s3fs 掛載后
df
顯示的空間是256T,並不是實際容量;官方解釋,如果有1PB的空間,顯示的256T並不影響實際的使用,只是使用率會超過100%。
dd文件吞吐測試
使用dd測試掛載后的硬盤性能,這里主要關注寫入速度。使用的命令
dd if=/dev/zero of=4G.${RANDOM} bs=1M count=4096 status=progress
默認的日志記錄在/var/log/messages
或者/var/log/syslog
中,默認日志級別是crit
;
使用-d
或者--debug
會將日志級別調整為info
。
使用dbglevel
調整日志級別,可選crit(critical), err(error), warn(warning), info(information)
。
兩個
-d
會將fuse的日志輸出到標准輸出。
-f
可以讓程序在前台運行,便於查看日志。
寫入過程
通過觀察日志發現,文件寫入分三個階段:
- 文件寫入到到fuse的某個地方,4G文件大概花費了9s;因為不太了解實現細節,這里用了某個地方。
- 文件分片,這部分也會花費一定的時間;時間和分片大小與並發有關。
- 文件上傳,這個階段才會占用帶寬。前兩個階段,實際上並沒有占用帶寬,但會占用時間,所以會拉低整體
dd
的帶寬。
三個階段的發現,通過觀察debug日志和實際網卡帶寬。
測試結果
千兆網卡,階段3可以跑滿帶寬,但因為階段1、2存在,整體帶寬只有80MB/s左右。
萬兆網卡實際測速大概是110MB/s。
使用
use_cache=/dev/shm
也可以加快1階段的速度。
另外,測試了goofys,千兆速度在100MB/s左右。萬兆網卡的速度在500~600MB/s
。相對於s3fs,goofys的使用有着更多的限制,參考current-status。
S3FS 的優缺點
S3FS本質上是對象存儲,其跟塊存儲還是有區別的,塊存儲我如果修改一個大文件的話,背后只修改對應的block;s3fs的修改是重傳,大文件的話就要考慮帶寬成本和修改速度。
主要適用於文件寫入后,不會被頻繁修改的場景。
Background Knowlage
Filesystem in Userspace
簡稱 FUSE
。它允許 Unix 普通用戶在不修改內核的條件下能夠創建自己的文件系統。目前 Linux 通過內核模塊對 FUSE 進行支持。一些文件系統如 ZFS、glusterfs 和 lustre 通過 FUSE 實現。