作者:張醫博
淺談
本章節結合一些實際遇到的案例講一下各種工具使用。
- 在遇到問題時先確保自己的工具一定是官方的最新迭代版本。
- 使用工具遇到問題時如果遇到 4xx 3xx 2xx 500 等問題,oss 都會返回一個 x-oss-requestID 的 http 頭,value 是一串字符,類似 5BEE7AD4C84D1C447120083C 這個對於排查分析問題非常重要。
- 每個工具基本都帶有 log 功能,請使用者務必開啟,遇到問題時可以追根溯源。
一、使用場景
- ossbrower,圖形版的操作工具,有控制檯的基本功能,可以理解是 ossutil 工具的圖形版,適用於一些非技術人員來操作 oss 。
- ossfs,將 oss mount 到本地放使用,利用的是 fuse 用戶態的文件系統,然後通過開源的 s3 協議和 oss 做了一個網絡映射,不推薦先敏感業務或者高併發使用,個人當作私人倉庫標適合。
- ossftp ,和開源的 ftp 一樣,將 oss 掛在本地後,當作遠程的倉庫上傳下載用。
- ossutil,目前 oss 對外工具性能最好,支持功能較多的高併發讀寫工具。操作易用,而且可以嵌入到腳本使用。
二、使用遇到問題
ossbrower
案例:駐雲工具無法加載 bucket 中 object
排查:
- 如圖是一個第一個非 oss 官方的第三方工具,用戶可以嘗試在客戶端做下基本的 ping 測試先看下網絡是否通。
- 檢查登陸的 AccesskeyID 的權限是否可以將 bucket 下的內容 list 出來。
- 用 ossbrower 測試下,看同樣的 AccesskeyID 登陸後是否也會報錯,如果 ossbrower 可以正常顯示,證明策略沒有問題,是第三方放工具的問題。可以聯繫駐雲公司看下是否配置上有特殊的地方。
案例:ossbrower 使用注意
- 如果登陸的 AK 沒有 AliYunOSSFullAccess 權限,截圖的位置必須要預設 endpoint;
- 遇到併發文件較多時,建議將任務數調大;
ossfs
ossfs 的報錯都會有明顯的 message,需要收集到這些 message,根據 message 判斷是否直接看出問題,比如 socket 建聯失敗,或者響應的狀態碼 4XX 5XX 等,一般 403 是權限問題被 deny ,400 是用戶的操作方法有誤,5xx 一般和網絡抖動以及客戶端業務有關係,使用前先將 debug-log 功能開啟。
如果使用 ossfs 發現性能很差,建議使用 ossutil,因為 ossfs 是將遠端的 OSS 掛載到本地磁盤,如果對業務性能敏感性很高的業務,不建議使用 ossfs ,而且該工具也不是原子性,存在本地操作成功,但 oss 遠端操作失敗的風險。
如果發現 ossfs 在 ls 目錄文件時很慢,可以增加調優參數 通過 -omax_stat_cache_size=xxx 參數增大 stat cache 的 size,這樣第一次ls會較慢,但是後續的ls就快了。
案例:ossfs 偶爾出現斷開的情況
排查:
- 出現問題後也不知原因,於是開啟了 ossfs 的 debug 日誌進行分析
加上 -d -o f2 參數,ossfs 會把日誌寫入到系統 /var/log/message
-日誌發現是 ossfs 在 listbucket listobject 申請內存過多,導致觸發了系統的 oom 將進行 killer ,找到了元凶。
- listobject 是要發起 http 請求到 oss 獲取一個 meta 信息,如果客戶的文件很多,ls 會消耗系統的大量內存來獲取文件的 meta,這是正常情況。
解決方案:
- 通過 -omax_stat_cache_size=xxx 參數增大 stat cache 的 size,這樣第一次 ls 會較慢,但是後續的 ls 就快了,因為文件的元數據都在本地 cache 中。默認這個值是1000,大約消耗 4MB 內存,請根據您機器內存大小調整為合適的值。
- 使用 ls -f 命令,這個命令會消除與 OSS 的 n 次 http 請求。
- ossfs 在讀寫時會佔用磁盤寫大量的 temp cache ,和 nginx 差不多,可能會導致磁盤空間不滿,最好能常清理一下。
- 使用 osstuil 替代 ossfs ,非線上敏感業務可以用 ossfs ,要求可靠性、穩定性的還是用 ossutil。
案例:訪問 403 deny
排查:
類這種有明顯報錯的很好判斷,明顯是 endpoint 指定錯誤。
- bucket 和 endpoint 不匹配
- bucket UID 和實際的 Accesskey 對應的 UID 不一致
案例:
cp 出現 input/output error
排查:
- 看下當時的磁盤讀寫是否出現高負載的情況。 io error 都是捕獲到這系統磁盤的錯誤。
- 可以嘗試增加分片參數,控制文件讀寫 , ossfs -h 看下 multipart 選項。
使用 rsync 同步出現 input/output error
- ossfs 與 rsync 同步使用會出現問題,而且用戶對一個 141G 的文件進行 cp 操作,對 ossfs 本身的磁盤讀寫比就是一個挑戰。
- 建議,如果想要將 oss 文件下載到本地 ECS ,或者本地上傳到 ECS ,可以通過 ossutil 的分片上傳、下載進行操作。
案例:
安裝依賴庫 fuse 報錯
排查:
出現這種問題都是 fuse 的版本不滿足 ossfs 的要求,2.8.3 的都不行,直接去 fuse 鏈接上下載最新版本的編譯安裝,不要用 yum, yum 安裝的都不是新版
參考鏈接:https://github.com/libfuse/libfuse
案例:
客戶使用 ossfs 上傳超過超過 100G 的文件出現
“there is no enough disk space for used as cache(or temporary)"
排查:
- 1) 先了解 ossfs 的大文件上傳原理,ossfs 上傳大文件,是通過分片來做的,默認分片時 10M,分片數量最大時 1000 個,也就是默認限制大小為 100G。
- 2) 出現這種本地磁盤空間不夠的情況,是因為 OSS 再上傳會寫一些臨時緩存文件到 /tmp 目錄下,再寫之前先要判斷下磁盤的管理空間是否小於用戶上傳的文件總量
// check free disk space
if(!FdManager::IsSafeDiskSpace(NULL, S3fsCurl::GetMultipartSize() * S3fsCurl::GetMaxParallelCount())){
S3FS_PRN_EXIT("There is no enough disk space for used as cache(or temporary) directory by s3fs.");
S3fsCurl::DestroyS3fsCurl();
s3fs_destroy_global_ssl();
exit(EXIT_FAILURE);
}
- 3) 而用戶上傳的文件是一個 300G 的文件,本地磁盤冗餘 600G,不可能不夠的,但是代碼統計不會說謊,當時磁盤空間預判確實不夠,ossfs 唯一能夠控制分片的就是 ,multipart_size 和 控制線程的數量。但是默認是 5 個,不可能是線程數量導致的,唯一可能就是 multipart_size 導致。通過分析發現用戶 multipart_size 是 300G * 5 = 1.5T,這個 multipart_size 分片大小是 M ,結果自然超過了本地的磁盤安全空間,所以導致的無法上傳,將分片大小降低後就解決了。
案例:
ossfs 掛載到本地,touch 文件出現 input/output error ,返回結果 403;
排查:
遇到類似問題,可以先使用 ossfs 的前臺掛載參數,將錯誤信息輸出到 console 上; -f -d -o curldbg -o dbglevel=info 有了 curl 的報錯日誌問題就比較好定位;
> PUT /.fuse_hidden0000000300000002 HTTP/1.1
Host: pgone.oss-cn-hangzhou-internal.aliyuncs.com
Accept: */*
Authorization: OSS LYnddfOj:l9hXsWS4KubHT+b0=
Content-Type: application/octet-stream
Date: Sat, 22 Dec 2018 11:52:22 GMT
User-Agent: aliyun-sdk-http/1.0()/ossfs1.80.5
x-oss-acl: private
x-oss-copy-source: /pgback/tmpn18XKo
x-oss-meta-gid: 0
x-oss-meta-mode: 33152
x-oss-meta-mtime: 1545479542
x-oss-meta-uid: 0
x-oss-metadata-directive: REPLACE
Content-Length: 0
Expect: 100-continue
< HTTP/1.1 100 Continue
< HTTP/1.1 403 Forbidden
< Server: AliyunOSS
< Date: Sat, 22 Dec 2018 11:52:22 GMT
< Content-Type: application/xml
< Content-Length: 331
< Connection: keep-alive
< x-oss-request-id: 5C1E2576D9D458BE30B9D539
< x-oss-server-time: 2
* HTTP error before end of send, stop sending
- 通過拿到的 http request、response 信息看到用戶有一個 rename 的操作,並且返回的 requestID 信息;
- 結合 ossfs 的源碼得知,ossfs 在掛載 oss 到本地成功後,會發起一個類似探針的操作進行 rename 和 chown 的操作,此過程是為了類似驗證 OSS 權限和連通性的操作;
- 如果出現類似的 copy 操作被 403 後,就需要您檢查下您的 bucket 是否為歸檔 bucket,如果不是歸檔繼續下面排查;
- 確認您的 Accesskey 對應的權限是否有對應的操作權限;
- 把 ossfs 卸載然後進入掛載的目錄看下直接 touch 會不會報錯;
如果以上仍不能解決您的問題,請將 requestID 提供到阿里雲進行排查。
ossutil
ossutil 目前沒有做限速功能,計劃支持中,目前真多多文件併發上傳是通過 --jobs(控制多個文件併發) --parallel(控制單一文件併發) 參數控制的。
案例:
ossutil 出現 skip 情況
[root@iZ2Sv4olcc4Z opt]# echo “testlil” > dskydb/test.txt
[root@iZ25v4olcc4Z opt]# ./ossutil64 cp -rt -c ~/.ossuti.Lcofig dskyclb/test.txt oss://gres/test.txt
Succeed: Total nun: 1, $ze: 30. OK nun: 1(upload 1 files).
0.372650(s) elapsed I
[root@iZ2Sv4olcc4Z opt] echo " ttest222r" >> dskydb/test.txt
[root@iZ2Sv4olcc4Z opt]. /ossutil64 cp —u —c ~/.ossutilconfig cbkydb/test.txt oss://gres/test.txt
Succeed: Total num: 1, ize: 38. OK nun: l(skip 1 files), Skip sin 38.
0.252878(s) elapsed
排查:
使用 -u 強制更新時,重新對所有的上傳文件和原的進行一次比對,發現美有更改的情況就會跳過,有發生更改的就會觸發上傳進行覆,正常情況。
遇到這種情況可以看下本地的 log 哪些文件被跳過了,將 oss 存儲的文件和本地文件做個 MD5 比對確保文件是一致。
命令:./ossutil64 cp -u -r -f aa.test oss://alihua -i -k -e
案例:ossutil 文件遞歸解凍時遇到 403
排查:
如圖用戶在操作解凍文件的過程中出現 403,可能與兩個原因有關係
- 用戶使用的子賬號操作文件,權限不夠。
- 用戶的文件是違禁內容被封禁掉了。
PS:遇到 403 時,遞歸解凍會中斷不會繼續。這種現象是正常的,工具在設計之初就是考慮到如果文件遇到 403 的話,代表沒有權限操作該文件,那麼通過該賬號下的其他文件也操作不了,所以就會中斷退出。
案例:ossutil 文件遞歸解凍時遇到 400
排查:
- 檢查用戶的命令和官方提供的命令是否完全一致,避免誤操作。
- 使用 stat 選項看一下文件的狀態是否是已經解凍了,如果以及解凍再次操作,就會出現 400。
案例:
ossutil 操作 object 出現 “The operation is not valid for the object's state”
排查:
出現這個問題是因為用戶操作的文件是一個歸檔的文件,不能直接操作,需要先進行解凍 restore 的操作後才能使用。
ossuti64 restore oss://bucket/prefix/object -I <accesskey> -k <secretkey> -e <endpoint>
遞歸解凍
ossuti64 restore oss://bucket/prefix/ -r -I <accesskey> -k <secretkey> -e <endpoint>
案例:
ossutil 掛載 crontab 中執行報錯
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0x6b4981]
goroutine 1 [running]:
github.com/aliyun/ossutil/lib.DecideConfigFile(0x0, 0x0, 0x7a8017, 0x7)
/Users/fengyu/go/src/github.com/aliyun/ossutil/lib/config_helper.go:57 +0x51
排查:
請直接下載 ossutil 的工具最近版本進行處理。這個問題已經解決掉。
http://gosspublic.alicdn.com/ossutil/1.4.2/ossutil64?spm=a2c4g.11186623.2.10.2ca74af8lGi3C8
案例:
Windows ossutil 上傳 OSS 速率慢不穩定
客戶端是在河北公網,目標服務端是北京,存在跨省情況;
首先了解下用戶在公網情況下,能否切換到同 region 的 OSS 上進行訪問,同 region 的 OSS 內網是有阿里環網組成,如果客戶只能在公網使用,進行下面的排查。
排查:
公網:
1) 首先看下用戶端 ping OSS 的完整域名的網絡 ping 值是否正常,tracert 是否有延遲抖動,此步驟可以通過腳本來做,下載腳本後運行,直接輸入完整的 OSS 域名即可; 腳本
- 腳本中是 ping 的是大包 1460,發現用戶端直接網絡超時,此時懷疑是客戶的網絡有限制或者網絡擁塞,但是 tracert 通的,再進行下一步排查;
- 嘗試降低 ping 包的 len 發現到 1412 ping 可以通過,說明客戶端在網絡上做限制,不允許 1460 大包的傳輸,影響了客戶端的上行網絡吞吐量;
2)嘗試檢查本機的網絡負載;
- 通過本機資源監控看用戶端當時的 CPU 負載和本機內存佔用較高,實際登陸到客戶端機器上發現系統卡頓,實際資源監控器看到 ossutil 工具線程並沒有跑到和設置的 --job=10 --parallel=10 (10*10=100)一樣,只是運行了 24 個,說明工具的線程受到了系統 CPU 調度影響,無法將網絡吞吐打上去,於是讓用戶關係了一些佔用 CPU 內存較高的應用後,ossutil 線程數終於打到 69;
調整前
調整後
3)靈活調整 ossutil 的線程數和分片的併發數;
- --bigfile-threshold=52428800 --jobs=10 --parallel=50 --part-size=52428800
- 遇到大文件數量多,以及單一的大文件時我們要靈活調整 ossutil 的相關參數能夠提高我們的 ossutil 的效率;
- 比如這個案例中客戶的文件大小平均是 100M 以上,而且客戶的出口帶寬是共享 200M ,也就是客戶自己的上線速度理論上也要 20M;
- 針對這種情況,我們可以把分片大小調整為 50M-10M,同時增加 parallel 分片的併發數量,儘可能的打滿上行的吞吐。當客戶端 CPU 核心比較少的時候不建議分的太小,比如分到 1M 時就會造成 CPU 切片過快,消耗 CPU 計算,影響系統性能。
- 如果遇到文件數量單一大文件,或者小文件時,可以不用加任何參數,直接上傳即可;調整完成後用戶的上行出口速率能打到 10M 大 B。
4)對比其他家的工具
- 比如七牛的 qfetch 以及 qshell 做了性能對比,上行的傳輸效率相差並不多,並沒有用戶反饋了七牛 20M (大B)阿里雲 4M(大B),基本上qshell 和 qfetch 的效果都是穩定在 10M 左右;
總結下問題以及需要客戶下一步解決:
當使用 ossbrower 上傳速度低時可以切換到 ossutil 這個高興的工具進行測試;
需要用戶解決下為什麼網絡出口限制的大包(1460) 的傳輸,這個問題不解決很難將網絡帶寬吞吐提上去。
儘量本機不要在負載高的情況下上傳一些大文件,如果傳輸的話可以關閉一些應用卡頓的程序,或者降低下 ossutil 工具的併發線程數量,不然即使設置了 100 ,但實際受到系統的 CPU 調用影響,不一定能跑到 100 。降低線程數,上傳的效率也會受到影響;
osscmd
案例:
OSS 存儲文件數量和本地的文件數量不符,用 ossutil 就是正確的。
排查:
osscmd 下載,是直接將 oss 雲存儲的 object 下載下來,不會包含 prefix ,有多少 object 就累計總和,不會出現誤差。
為什麼 oss 存儲的比 osscmd 統計的多?
- 因為 oss 上的 prefix 也算是一個 object ,oss 上一切都是文件,沒有目錄的概念,prefix 被認為是 object 計算後,總的數量就會比 osscmd 看到的多。
- 要想判斷是否有失敗文件,只要關心 fail num 的數量即可,為 0 代標沒有失敗的,skip 如果不為 0 說明用戶之前有下載過文件,又重複下載一遍,但是文件內容沒更新所以被計到 skip 中。
為什麼 ossutil 正常? - 因為 ossutil 下載是將整個目錄結構下載下來,統計的方式是和 OSS 一致的,將 prefix 也計算在 object 中,所以和 OSS 雲端看到的一致。