本文介紹在使用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操作失敗的可能原因是源檔案為Archive Storage、冷Archive Storage或者深度冷Archive Storage類型檔案。
解決方案:對Archive Storage、冷Archive Storage或者深度冷Archive Storage類型的檔案執行mv操作前,您需要先解凍檔案。具體步驟,請參見解凍檔案。
ossfs是否支援在Windows環境中掛載儲存空間?
不支援。您可以在Windows環境下,通過Rclone掛載儲存空間。具體步驟,請參見Rclone。
ossfs是否支援將OSS儲存空間掛載至多台Linux ECS伺服器?
支援。您可以多次將其掛載至Linux ECS伺服器中。具體步驟,請參見ossfs配置與掛載。
為什麼用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。