s3fs把 s3-like 對象存儲掛載到本地


s3fs-fuse 是一個采用 c++🚀 開發的開源應用,它的作用是可以將 AWS S3 以及兼容 S3 API 的第三方對象存儲像普通文件系統一樣掛載到本地計算機,由於這種功能通過 FUSE 實現,因此只能在 Linux 和 MacOS 上使用。

安裝

安裝參考📙

官方編譯安裝參考wiki 🍌

配置

  1. 准備密碼文件

S3 及兼容 API 的對象存儲都采用 ACCESS KEYACCESS SECRET 認證身份,為了方便配置,可以將認證 KEY 放到獨立的密碼文件中,s3fs 默認會從以下兩個文件中讀取認證信息:

  • 用戶家目錄下的 .passwd-s3fs 文件 (例如 ~/.passwd-s3fs)
  • 全局文件 /etc/passwd-s3fs

任選其一即可,文件默認不存在,需要自己手動創建。

$ echo ACCESS_KEY_ID:SECRET_ACCESS_KEY >  ~/.passwd-s3fs
$ chmod 600  ~/.passwd-s3fs
  1. 掛載 AWS S3
$ s3fs mybucket /path/to/mountpoint -o passwd_file=~/.passwd-s3fs
  • mybucket 替換成實際的 S3 Bucket
  • /path/to/mountpoint 替換成本地掛載點
  • -o 用來指定額外的參數,除非密碼文件沒有放在默認位置,否則不需指定密碼文件。
  1. 掛載兼容 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 和七牛對象存儲不需指定該參數。

  1. 開機自動掛載

編輯 /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 保存密碼。

  1. 其他參數
  • 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

使用記錄

  1. s3fs 掛載后 df 顯示的空間是256T,並不是實際容量;官方解釋,如果有1PB的空間,顯示的256T並不影響實際的使用,只是使用率會超過100%。
    15-00-18-d4uyo4

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可以讓程序在前台運行,便於查看日志。

寫入過程

通過觀察日志發現,文件寫入分三個階段:

  1. 文件寫入到到fuse的某個地方,4G文件大概花費了9s;因為不太了解實現細節,這里用了某個地方
  2. 文件分片,這部分也會花費一定的時間;時間和分片大小與並發有關。
  3. 文件上傳,這個階段才會占用帶寬。前兩個階段,實際上並沒有占用帶寬,但會占用時間,所以會拉低整體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 實現。

🌴Reference


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM