本文介紹在使用ossfs時遇到的一些問題案例及解決方案。
通用說明
ossfs報錯信息中均包含message。排查問題時,需要收集這些message,并根據message判斷問題。例如socket連接失敗、HTTP響應的狀態碼4xx、5xx等,使用前先開啟debug-log。
403錯誤是因權限不足,導致訪問被拒絕。
400錯誤是用戶的操作方法有誤。
5xx錯誤一般和網絡抖動以及客戶端業務有關系。
ossfs有以下特點:
ossfs是將遠端的OSS掛載到本地磁盤,如果對文件讀寫性能敏感的業務,不建議使用ossfs 。
ossfs的操作不是原子性,存在本地操作成功,但OSS遠端操作失敗的風險。
如果ossfs不滿足您的業務需求,建議使用ossutil。
權限問題
掛載成功后,touch文件時報錯403
問題分析:403錯誤通常是訪問權限問題導致的。以下情況會導致touch一個文件出現403報錯。
該文件為歸檔類型文件,touch時會出現403報錯。
使用的AccessKey無該存儲空間的操作權限。
解決方案:
歸檔類型文件問題:將文件解凍后訪問或為文件所在Bucket開啟歸檔直讀。
權限問題:為使用的AccessKey對應的賬號配置正確的權限。
通過rm命令刪除文件時報錯"Operation not permitted"
問題分析:通過rm命令刪除文件時,會調用DeleteObject API進行刪除。如果您是通過RAM用戶掛載,請檢查掛載的RAM用戶是否具備刪除文件的權限。
解決方案:為該RAM用戶設置正確的權限。更多信息,請參見RAM Policy和RAM Policy常見示例。
訪問報錯"The bucket you are attempting to access must be addressed using the specified endpoint”
問題分析:根據Message判斷,錯誤原因是Endpoint指定錯誤,有以下兩種可能性:
Bucket和Endpoint不匹配。
Bucket所屬UID和實際的AccessKey對應的UID不一致。
解決方案:確認配置信息正確并修改。
掛載問題
掛載報錯"ossfs: unable to access MOUNTPOINT /tmp/ossfs: Transport endpoint is not connected"
問題分析:未創建該目錄導致的。
解決方案:先創建對應的目錄,之后再進行掛載操作。
掛載報錯"fusermount: failed to open current directory: Permission denied"
問題分析:fuse的Bug,要求當前用戶對當前目錄(非掛載目錄)有讀權限。
解決方案:通過cd命令切換到一個有讀權限的目錄,再運行ossfs命令。
掛載報錯"ossfs: Mountpoint directory /tmp/ossfs is not empty. if you are sure this is safe, can use the 'nonempty' mount option"
問題分析:默認情況下,ossfs只能掛載到空目錄下。當試圖掛載到非空目錄下時,會提示上述錯誤。
解決方案:切換到一個空目錄下重新掛載。如果還是需要掛載到該目錄下,掛載時增加 -ononempty 參數。
掛載報錯"ops-nginx-12-32 s3fs[163588]: [tid-75593]curl.cpp:CurlProgress(532): timeout now: 1656407871, curl_times[curl]: 1656407810, readwrite_timeout: 60"
問題分析:ossfs掛載超時。
解決方案:ossfs通過readwrite_timeout選項指定讀或者寫請求的超時時間,單位為秒,默認值為60秒。您需要結合實際業務場景,適當增加該選項的取值。
掛載報錯"ossfs: credentials file /etc/passwd-ossfs should not have others permissions"
問題分析:/etc/passwd-ossfs文件權限不正確。
解決方案:/etc/passwd-ossfs保留了訪問憑證信息,需要限制others訪問該文件。您可以通過chmod 640 /etc/passwd-ossfs
命令修改文件的訪問權限。
掛載成功后,ls目錄時報錯"operation not permitted"
問題分析:請檢查您的Bucket中,是否存在名稱含有不可見字符的Object。文件系統對文件名和目錄名有嚴格的限制,因此會收到上述錯誤。
解決方案:用其他工具對這些Object重命名后,ls就能正確顯示目錄內容了。
掛載時報錯"fuse: device not found, try 'modprobe fuse'"
問題分析:嘗試在Docker容器中使用ossfs掛載時遇到的錯誤"fuse: device not found, try 'modprobe fuse'"通常是因為容器缺乏訪問或加載FUSE內核模塊所需的權限。
解決方案:在Docker容器中運行時,可以通過添加--privileged=true
參數來賦予容器更高的權限,從而允許容器內的進程執行類似宿主機的操作,包括使用FUSE文件系統。使用--privileged
標志啟動容器的命令示例如下:
docker run --privileged=true -d your_image
費用問題
在ECS上掛載OSS,如何避免因后臺程序掃描文件而產生費用
問題分析:程序掃描ossfs掛載的目錄,會轉換成向OSS的請求。如果請求次數很多,會產生費用。
解決方案:可以通過auditd工具查看是哪些進程掃描了OSS掛載的目錄。具體步驟如下:
安裝auditd并啟動。
sudo apt-get install auditd sudo service auditd start
將OSS掛載的目錄設置為監視目錄,例如掛載目錄為/mnt/ossfs。
auditctl -w /mnt/ossfs
在auditlog中查看是哪些進程訪問了這個目錄。
ausearch -i | grep /mnt/ossfs
修改參數,跳過程序掃描。
例如通過auditlog查到是updatedb掃描了所掛載的目錄,可以通過修改/etc/updatedb.conf讓它跳過。具體做法是:
在
RUNEFS =
后面加上fuse.ossfs
。在
PRUNEPATHS =
后面加上掛載的目錄。
磁盤內存問題
ossfs偶爾出現斷開的情況
問題分析:
開啟ossfs的debug日志,加上-d -odbglevel=dbg參數,ossfs會將日志寫入到默認系統文件中。
CentOS系統:寫入到
/var/log/message
。Ubuntu系統:寫入到
/var/log/
syslog。
分析日志,發現ossfs在listbucket、listobject申請內存過多,觸發了系統的oom。
說明listobject是發起HTTP請求到OSS獲取文件的meta信息,如果客戶的文件很多,ls會消耗系統大量內存來獲取文件的meta。
解決方案:
通過-omax_stat_cache_size=xxx參數增大stat cache 的 size,這樣第一次ls會較慢,但是后續的ls速度會提高,因為文件的元數據都在本地cache中。這個值默認是1000,約消耗4 MB內存,請根據您機器內存大小調整為合適的值。
ossfs在讀寫時會占用磁盤寫大量的temp cache ,和Nginx差不多,可能會導致磁盤可用空間不足。當ossfs退出后,會自動清理臨時文件。
使用ossutil替代ossfs,非線上敏感業務可以使用ossfs ,要求可靠性、穩定性的建議使用ossutil。
ossfs為什么會把磁盤空間寫滿?
問題原因:為提升性能,默認情況下ossfs會盡可能使用磁盤空間來保存上傳或下載的臨時數據,此時會存在磁盤空間寫滿的情況。
解決方法:您可以通過-oensure_diskfree選項指定保留磁盤空間大小。例如,指定保留20 GB的磁盤空間大小,命令如下:
ossfs examplebucket /tmp/ossfs -o url=http://oss-cn-hangzhou.aliyuncs.com -oensure_diskfree=20480
ossfs掛載后,為什么通過df命令顯示磁盤空間大小為256 TB?
通過df命令顯示的磁盤空間大小僅作為展示值,并不代表OSS存儲空間實際容量。其中,Size(磁盤空間總大小)和Avail(磁盤空間剩余可用大小)固定為256 TB,Used(已使用磁盤空間大小)固定為0 TB。
OSS存儲空間容量無限制,存儲空間使用量取決于您的實際使用量。關于存儲空間用量查詢的更多信息,請參見查詢Bucket級別的用量情況。
通過cp命令拷貝數據時報錯"input/output error"
問題分析:input/output error都是捕獲到系統磁盤的錯誤而產生的報錯,可以查看出現報錯時,磁盤讀寫是否存在高負載的情況。
解決方案:可以增加分片參數,控制文件讀寫。使用ossfs -h命令可以查看分片參數。
使用rsync同步時報錯"input/output error"
問題分析:ossfs與rsync同步使用本身會出現問題。此案例中,用戶對一個141 GB的大文件進行cp操作,使磁盤讀寫處于非常高的負載狀態,從而產生此報錯。
解決方案:如果想要將OSS文件下載到本地ECS ,或者本地上傳到ECS ,可以通過ossutil的分片上傳、下載進行操作。
上傳大文件時報錯"there is no enough disk space for used as cache(or temporary)"
問題原因
磁盤空間小于
multipart_size * parallel_count
。multipart_size表示分片大小(默認單位為MB),parallel_count表示并發上傳分片數量(默認值為5)。
問題分析
ossfs默認通過分片上傳的方式上傳大文件。上傳時,ossfs會將臨時緩存文件寫入/tmp目錄下,寫入前需要先判斷/tmp目錄所在的磁盤可用空間是否小于
multipart_size * parallel_count
。如果磁盤可用空間大于multipart_size * parallel_count
,則正常寫入文件。如果磁盤可用空間小于multipart_size * parallel_count
,則出現本地磁盤可用空間不足的報錯。例如,磁盤可用空間為300 GB,待上傳的文件為200 GB,但multipart_size設置為100000(100 GB),并發上傳分片數量保持默認值5。此時,ossfs判斷上傳的文件大小為100 GB*5=500 GB,超出本地磁盤可用空間。
解決方法
在并發上傳分片數量保持默認值5的情況下,設置合理的multipart_size:
如果磁盤可用空間為300 GB,待上傳的文件為200 GB,則multipart_size設置為20。
如果磁盤可用空間為300 GB,待上傳的文件為500 GB,則multipart_size設置為50。
版本依賴問題
安裝ossfs時報錯"fuse: warning: library too old, some operations may not work"
問題分析:出現錯誤的原因是ossfs編譯時所使用的libfuse版本比運行時鏈接到的libfuse版本高,這往往是用戶自行安裝了libfuse導致的。CentOS-5.x和CentOS-6.x系統中,阿里云提供的ossfs安裝包里包含了libfuse-2.8.4,如果在運行的時候環境中有libfuse-2.8.3,并且ossfs被鏈接到了舊版本的fuse上,就會出現上述錯誤。
您可以通過ldd $(which ossfs) | grep fuse命令確認ossfs運行時鏈接的fuse版本,如結果是/lib64/libfuse.so.2,那么通過ls -l /lib64/libfuse*命令可以看到fuse的版本。
解決方案:讓ossfs鏈接到正確的版本。
通過rpm -ql ossfs | grep fuse命令找到libfuse的目錄。
如果結果是/usr/lib/libfuse.so.2,則通過LD_LIBRARY_PATH=/usr/lib ossfs …命令運行ossfs。
安裝依賴庫fuse報錯
問題分析:fuse的版本不滿足ossfs的要求。
解決方案:手動下載fuse最新版本安裝,不要使用yum安裝。詳情請參見fuse。
使用Is列舉文件時報錯"Input/Output error"
問題原因:該問題主要出現在CentOS環境,日志中報錯NSS error -8023
。ossfs在使用libcurl進行HTTPS通信時出現問題,可能是由于libcurl依賴的NSS(Network Security Services)庫版本過低導致的。
解決方案:使用以下代碼,升級NSS庫至最新版本。
yum update nss
使用yum/apt-get安裝ossfs時報錯"conflicts with file from package fuse-devel"
問題分析:系統中存在老版本的fuse,與ossfs里的依賴版本沖突。
解決方案:請先使用相關的包管理器卸載fuse,再重新安裝ossfs。
其他問題
使用ossfs上傳到OSS的文件的Content-Type全是application/octet-stream
問題分析:上傳文件時,ossfs通過查詢/etc/mime.types中的內容來設置文件的Content-Type。當該文件不存在時,默認設置為application/octet-stream。
解決方案:請檢查這個文件是否存在,如果不存在,則需要添加。
通過命令自動添加mime.types文件
Ubuntu系統
使用sudo apt-get install mime-support命令添加。
CentOS系統
使用sudo yum install mailcap命令添加。
手動添加mime.types文件
創建mime.types文件
vi /etc/mime.types
添加需要的格式,每種格式一行,每行格式為
application/javascript js
。
添加完成后,需要重新掛載OSS。
ossfs為什么將文件夾識別成普通文件
情形一:
問題分析:創建文件夾對象(以
/
結尾的對象)時,content-type指定為text/plain,ossfs會將這個對象識別成普通文件。解決方案:您可以掛載時加上-ocomplement_stat參數。如果該文件夾對象大小為0或1,ossfs會將其識別成文件夾。
情形二:
問題分析:可以通過
ossutil stat 文件夾對象(以'/'結尾)
命令(例如:ossutil stat oss://[bucket]/folder/
)。執行命令后:查看該對象的Content-Length字段,即對象的大小。如果對象大小非0,則會被識別成文件。
解決方案:如果不再需要該文件夾對象的內容,可以通過
ossutil rm oss://[bucket]/folder/
命令刪除該對象(不會影響文件夾下面的文件),或者通過ossutil上傳一個大小為0的同名對象將其覆蓋。如果對象大小為0,查看Content-Type字段,即對象屬性,如果不是
application/x-directory
,httpd/unix-directory
,binary/octet-stream
或application/octet-stream
,也會被識別成文件。解決方案:可以通過
ossutil rm oss://[bucket]/folder/
命令刪除該對象(不會影響文件夾下面的文件)
ossfs執行mv操作失敗
問題原因:通過ossfs執行mv操作失敗的可能原因是源文件為歸檔存儲、冷歸檔存儲或者深度冷歸檔存儲類型文件。
解決方法:對歸檔存儲、冷歸檔存儲或者深度冷歸檔存儲類型的文件執行mv操作前,您需要先解凍文件。具體步驟,請參見解凍文件。
ossfs是否支持在Windows環境中掛載存儲空間?
不支持。您可以在Windows環境下,通過以下兩種方式掛載OSS存儲空間。
通過云存儲網關掛載存儲空間。具體步驟,請參見通過云存儲網關掛載OSS。
通過Rclone掛載存儲空間。具體步驟,請參見Rclone。
為什么用ossfs看到的文件信息(例如大小)與其他工具看到的不一致
問題分析:ossfs默認會緩存文件的元數據(包括大小/權限等),這樣就不需要每次ls的時候向OSS發送請求,加快速度。 如果用戶通過其他程序(例如SDK/官網控制臺/ossutil等)對文件進行了修改,由于緩存的關系,ossfs沒有及時更新,導致與其他工具看到的文件信息不一致。
解決方案:可以在掛載的時候加上參數-omax_stat_cache_size=0,禁用元數據緩存功能。每次ls時,都會向OSS 發送請求,獲取最新的文件信息。
為什么Bucket開啟版本控制后出現掛載慢的問題?
問題原因:ossfs默認通過調用ListObjects(GetBucket)列舉文件。在Bucket開啟版本控制,且Bucket中存在一個或者多個歷史版本Object以及大量的過期刪除標記的情況下,使用ListObjects(GetBucket)接口列舉當前版本Object時會出現響應速度下降,從而影響ossfs掛載操作。
解決方法:使用-olistobjectsV2選項將ossfs切換至ListObjectsV2(GetBucketV2)接口,提升列舉文件的性能。
如何設置通過HTTPS方式掛載?
ossfs支持通過HTTPS方式掛載,以華東1(杭州)地域為例,掛載命令如下:
ossfs examplebucket /tmp/ossfs -o url=https://oss-cn-hangzhou.aliyuncs.com
目錄下有非常多的文件時,為什么ls該目錄很慢
問題分析:假設一個目錄下有N個文件,那么ls該目錄至少需要N次OSS HTTP requests。在文件非常多的時候,這可能造成嚴重的性能問題。
解決方案: 通過-omax_stat_cache_size=xxx
參數增大stat cache的size,這樣第一次ls會較慢,但是后續的ls就快了,因為文件的元數據都在本地cache中。在1.91.1版本之前,這個值默認是1000;從1.91.1版本開始,這個值默認是100000,內存占用約幾十MB,請根據您機器內存大小調整為合適的值。
卸載時報錯"fusermount: failed to unmount /mnt/ossfs-bucket: Device or resource busy"
問題分析:有進程正在訪問掛載目錄/mnt/ossfs-bucket下的文件 ,所以無法卸載。
解決方案:
使用
lsof /mnt/ossfs-bucket
找出訪問該目錄的進程。使用kill命令強制關閉進程。
使用
fusermount -u /mnt/ossfs-bucket
卸載Bucket。