天天看點

OSS 工具集

作者:張醫博

淺談

本章節結合一些實際遇到的案例講一下各種工具使用。

  • 在遇到問題時先確定自己的工具一定是官方的最新疊代版本。
  • 使用工具遇到問題時如果遇到 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 工具集

排查:

  • 如圖是一個第一個非 oss 官方的第三方工具,使用者可以嘗試在用戶端做下基本的 ping 測試先看下網絡是否通。
  • 檢查登陸的 AccesskeyID 的權限是否可以将 bucket 下的内容 list 出來。
  • 用 ossbrower 測試下,看同樣的 AccesskeyID 登陸後是否也會報錯,如果 ossbrower 可以正常顯示,證明政策沒有問題,是第三方放工具的問題。可以聯系駐雲公司看下是否配置上有特殊的地方。

案例:ossbrower 使用注意

  • 如果登陸的 AK 沒有 AliYunOSSFullAccess 權限,截圖的位置必須要預設 endpoint;
    OSS 工具集
  • 遇到并發檔案較多時,建議将任務數調大;
    OSS 工具集

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 偶爾出現斷開的情況

OSS 工具集

  • 出現問題後也不知原因,于是開啟了 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

OSS 工具集

類這種有明顯報錯的很好判斷,明顯是 endpoint 指定錯誤。

  • bucket 和 endpoint 不比對
  • bucket UID 和實際的 Accesskey 對應的 UID 不一緻

案例:

cp 出現 input/output error

OSS 工具集

  • 看下當時的磁盤讀寫是否出現高負載的情況。 io error 都是捕獲到這系統磁盤的錯誤。
  • 可以嘗試增加分片參數,控制檔案讀寫 , ossfs -h 看下 multipart 選項。

    使用 rsync 同步出現 input/output error

OSS 工具集
  • ossfs 與 rsync 同步使用會出現問題,而且使用者對一個 141G 的檔案進行 cp 操作,對 ossfs 本身的磁盤讀寫比就是一個挑戰。
  • 建議,如果想要将 oss 檔案下載下傳到本地 ECS ,或者本地上傳到 ECS ,可以通過 ossutil 的分片上傳、下載下傳進行操作。

安裝依賴庫 fuse 報錯

OSS 工具集

出現這種問題都是 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)"

OSS 工具集

  • 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;

OSS 工具集

遇到類似問題,可以先使用 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

OSS 工具集

如圖使用者在操作解凍檔案的過程中出現 403,可能與兩個原因有關系

  • 使用者使用的子賬号操作檔案,權限不夠。
  • 使用者的檔案是違禁内容被封禁掉了。

    PS:遇到 403 時,遞歸解凍會中斷不會繼續。這種現象是正常的,工具在設計之初就是考慮到如果檔案遇到 403 的話,代表沒有權限操作該檔案,那麼通過該賬号下的其他檔案也操作不了,是以就會中斷退出。

案例:ossutil 檔案遞歸解凍時遇到 400

OSS 工具集

  • 檢查使用者的指令和官方提供的指令是否完全一緻,避免誤操作。
  • 使用 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 速率慢不穩定

用戶端是在河北公網,目标服務端是北京,存在跨省情況;

OSS 工具集

首先了解下使用者在公網情況下,能否切換到同 region 的 OSS 上進行通路,同 region 的 OSS 内網是有阿裡環網組成,如果客戶隻能在公網使用,進行下面的排查。

公網:

1) 首先看下使用者端 ping OSS 的完整域名的網絡 ping 值是否正常,tracert 是否有延遲抖動,此步驟可以通過腳本來做,下載下傳腳本後運作,直接輸入完整的 OSS 域名即可; 腳本

  • 腳本中是 ping 的是大包 1460,發現使用者端直接網絡逾時,此時懷疑是客戶的網絡有限制或者網絡擁塞,但是 tracert 通的,再進行下一步排查;
    OSS 工具集
  • 嘗試降低 ping 包的 len 發現到 1412 ping 可以通過,說明用戶端在網絡上做限制,不允許 1460 大包的傳輸,影響了用戶端的上行網絡吞吐量;
    OSS 工具集

2)嘗試檢查本機的網絡負載;

  • 通過本機資源監控看使用者端當時的 CPU 負載和本機記憶體占用較高,實際登陸到用戶端機器上發現系統卡頓,實際資源監控器看到 ossutil 工具線程并沒有跑到和設定的 --job=10 --parallel=10 (10*10=100)一樣,隻是運作了 24 個,說明工具的線程受到了系統 CPU 排程影響,無法将網絡吞吐打上去,于是讓使用者關系了一些占用 CPU 記憶體較高的應用後,ossutil 線程數終于打到 69;

    調整前

OSS 工具集

調整後

OSS 工具集

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 就是正确的。

OSS 工具集

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 雲端看到的一緻。

繼續閱讀