【最佳實踐】OSS開源工具ossutil-增量上傳

zuozhao發表於2018-06-12

經常碰到內部同學或者外部客戶問ossutil關於增量上傳的問題。本文簡單描述下原理並舉例說明。

使用者可從這裡獲取ossutil。

官網:https://help.aliyun.com/document_detail/50452.html
程式碼:https://github.com/aliyun/ossutil

應用場景

場景一

某使用者有一批檔案(比如1000個)要上傳到OSS(或從OSS下載,或從OSS拷貝到OSS,下同),當執行批量上傳的過程中出現失敗(比如在上傳第601個檔案時失敗)。使用者立即使用相同命令重新上傳,並希望能跳過已經成功上傳的檔案,實現增量上傳。

場景二

考慮這樣一個場景,某使用者有個目錄dir1,連續一週每天往裡面寫10000個檔案(比如監控場景等),每天晚上12:00將當天寫入的檔案上傳至OSS。使用者希望後續每天上傳當天寫入的新檔案時能快速跳過前一天已經上傳的檔案,從而實現加速增量上傳。

ossutil相關選項

–update/-u

選項說明

如果指定了該選項,只有以下情況,ossuti才執行上傳、下載、拷貝

  • 目標檔案(或object)不存在
  • 原始檔(或object)新於目標檔案(或object)

當指定了該選項時,無論是否指定了–force選項,當目標檔案存在時,ossutil都不會提示,直接採取上述策略。

該選項可用於場景一。

例子

單個上傳

$ cat a
########################
aaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaa

# 正常上傳

$ ossutil cp a oss://tempb3
Succeed: Total num: 1, size: 125. OK num: 1(upload 1 files).
0.176370(s) elapsed

$ ossutil ls oss://tempb3/a
LastModifiedTime                   Size(B)  StorageClass   ETAG                                  ObjectName
2018-06-08 10:45:58 +0800 CST           75      Standard   0CA6EECDD13AE2CD9B5246B071288EAB      oss://tempb3/a
  • 修改內容再加-u上傳

    • 可以看到該檔案被上傳,上傳後是新的內容,因為last modify不同
$ cat a
########################
aaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbb

# 若直接上傳,會詢問

ossutil cp a oss://tempb3
cp: overwrite "oss://tempb3/a"(y or N)? n
Succeed: Total num: 1, size: 125. OK num: 1(skip 1 files), Skip size: 125.
2.685027(s) elapsed
# 指定-u選項,不管有沒有-force均會上傳

$ ossutil cp a oss://tempb3 -u
Succeed: Total num: 1, size: 125. OK num: 1(upload 1 files).
0.173988(s) elapsed

$ ossutil ls oss://tempb3/a
LastModifiedTime                   Size(B)  StorageClass   ETAG                                  ObjectName
2018-06-08 10:47:10 +0800 CST          125      Standard   325DD8C33F1D4FACBF2994A71D1F20F7      oss://tempb3/a
Object Number is: 1
0.102570(s) elapsed
  • 不改變內容,再加-u上傳

    • 可以看到該檔案被skip掉,因為last modify相同
$ ossutil cp a oss://tempb3 -u
Succeed: Total num: 1, size: 125. OK num: 1(skip 1 files), Skip size: 125.
0.183596(s) elapsed

$ ossutil ls oss://tempb3/a
LastModifiedTime                   Size(B)  StorageClass   ETAG                                  ObjectName
2018-06-08 10:47:10 +0800 CST          125      Standard   325DD8C33F1D4FACBF2994A71D1F20F7      oss://tempb3/a
Object Number is: 1
0.099396(s) elapsed

批量上傳

# 測試目錄下共200個檔案

$ ls testdir | wc -l
     200

# 上傳41個檔案後Ctrl+C掉

$ ossutil cp testdir/ oss://tempb3 -r
Total num: 200, size: 2,048,000. Dealed num: 39(upload 39 files), OK size: 419,840, Progress: 20%^C⏎       =========> 此處Ctrl+C掉,下同

$ ossutil ls oss://tempb3
LastModifiedTime                   Size(B)  StorageClass   ETAG                                  ObjectName
2018-06-08 11:25:50 +0800 CST        10240      Standard   1276481102F218C981E0324180BAFD9F      oss://tempb3/testfile1.jpg
2018-06-08 11:25:50 +0800 CST        10240      Standard   1276481102F218C981E0324180BAFD9F      oss://tempb3/testfile10.jpg
2018-06-08 11:25:50 +0800 CST        10240      Standard   1276481102F218C981E0324180BAFD9F      oss://tempb3/testfile100.jpg
2018-06-08 11:25:51 +0800 CST        10240      Standard   1276481102F218C981E0324180BAFD9F      oss://tempb3/testfile101.jpg
...
2018-06-08 11:25:52 +0800 CST        10240      Standard   1276481102F218C981E0324180BAFD9F      oss://tempb3/testfile135.jpg
Object Number is: 41       =========> 成功上傳41個檔案
0.054455(s) elapsed
# 不加-u或-f選項,不會跳過已成功上傳的檔案,並會對每個檔案詢問

$ ossutil cp testdir/ oss://tempb3 -r
cp: overwrite "oss://tempb3/testfile10.jpg"(y or N)? y
cp: overwrite "oss://tempb3/testfile1.jpg"(y or N)? y
cp: overwrite "oss://tempb3/testfile100.jpg"(y or N)? y
cp: overwrite "oss://tempb3/testfile101.jpg"(y or N)? ^C⏎
# 加-u選項,會跳過已成功上傳的檔案

$ ossutil cp testdir/ oss://tempb3 -r -u
Total num: 200, size: 2,048,000. Dealed num: 79(upload 38 files, skip 41 files), OK size: 819,200, Progress: 40%^C⏎       =========> skip掉已成功上傳的41個檔案   

$ ossutil cp testdir/ oss://tempb3 -r -u
Total num: 200, size: 2,048,000. Dealed num: 91(upload 12 files, skip 79 files), OK size: 942,080, Progress: 46%^C⏎       =========> skip掉已成功上傳的79個檔案

$ ossutil cp testdir/ oss://tempb3 -r -u
Succeed: Total num: 200, size: 2,048,000. OK num: 200(upload 108 files, skip 92 files), Skip size: 942,080.       =========> skip掉已成功上傳的92個檔案直到上傳所有檔案
5.128975(s) elapsed

–snapshot-path

選項說明

該選項用於在某些場景下加速增量上傳批量檔案(目前,下載和拷貝不支援該選項)。如上述場景二。但要求兩次上傳期間使用者沒有修改OSS上對應的object。

若上傳檔案時指定了該選項,

  • 若指定的snapshot-path不存在,ossutil將建立該目錄,並在該目錄下生成檔案記錄檔案上傳的快照資訊;
  • 若指定的目錄存在,ossutil則讀取該目錄下的快照資訊並進行增量上傳(只上傳上次未成功上傳的檔案和本地進行過修改的檔案)並更新快照資訊;

注意

  • 使用者指定的snapshot-path必須為本地檔案系統上的可寫目錄;
  • 因為該命令通過在本地記錄成功上傳的檔案的本地lastModifiedTime,從而在下次上傳時通過比較lastModifiedTime來決定是否跳過相同檔案的上傳,所以在使用該選項時,請確保兩次上傳期間使用者沒有修改OSS上對應的object。當不滿足該場景時,如果想要增量上傳批量檔案,請使用–update選項。
  • ossutil不會主動刪除snapshot-path下的快照資訊,為了避免快照資訊過多,當使用者確定快照資訊無用時,請使用者自行清理snapshot-path。

例子

  • 先往testdir/目錄下寫1000個檔案,並將這1000個檔案上傳至OSS
$ ls testdir | wc -l
    1000

$ ossutil cp testdir/ oss://tempb3 -r --snapshot-path=test_snapshot
Succeed: Total num: 1000, size: 10,240,000. OK num: 1000(upload 1000 files).
21.711238(s) elapsed
可以看到在test_snapshot下面生成了如下檔案。其中000001.log裡面存放已經上傳成功的檔案的本地LastModified的值。

$ ls test_snapshot/
000001.log      CURRENT         LOCK            LOG             MANIFEST-000000

# 擷取其中幾個檔案的資訊

1528429733,ú /¦`^@^A^C^@^@^@^@^@^@^@^A^@^@^@^AG/Users/tester/ws/testdir/testfile10.jpg==>oss://tempb3/testfile10.jpg
1528429730@N ûb^@^A^D^@^@^@^@^@^@^@^A^@^@^@^AI/Users/tester/ws/testdir/testfile101.jpg==>oss://tempb3/testfile101.jpg
1528429731r^X><b^@^A^E^@^@^@^@^@^@^@^A^@^@^@^AI/Users/tester/ws/testdir/testfile102.jpg==>oss://tempb3/testfile102.jpg
1528429731ôë^Fù b^@^A^F^@^@^@^@^@^@^@^A^@^@^@^AI/Users/tester/ws/testdir/testfile103.jpg==>oss://tempb3/testfile103.jpg

# 比如 testfile10.jpg的LastModified值

$ date -d@1528429733
Fri Jun  8 11:48:53 CST 2018
  • 假設往testdir/目錄下新寫了1000個檔案,並將新寫入的1000個檔案上傳至OSS。
$ ossutil cp testdir/ oss://tempb3 -r --snapshot-path=test_snapshot
Total num: 2007, size: 30,720,503. Dealed num: 1163(upload 161 files, 2 directories, skip 1000 files), OK size: 13,496,823, Progress: 43%^C           =========> 已經上傳成功的1000個檔案被skip

$ ossutil cp testdir/ oss://tempb3 -r --snapshot-path=test_snapshot
Succeed: Total num: 2007, size: 30,720,503. OK num: 2007(upload 844 files, skip 1163 files), Skip size: 14,111,223.           =========> 已經上傳成功的11163個檔案被skip
18.345646(s) elapsed

$ ossutil cp testdir/ oss://tempb3 -r --snapshot-path=test_snapshot
Succeed: Total num: 2007, size: 30,720,503. OK num: 2007(skip 2007 files), Skip size: 30,720,503.
0.039435(s) elapsed           =========> 已經上傳成功的2007個檔案被skip

區別與聯絡

二者可同時指定。當同時指定時,

  • ossutil會優先根據snapshot-path資訊判斷是否跳過上傳,如果不滿足跳過條件,再根據–update判斷是否跳過上傳;
  • 一旦指定了這兩種增量上傳策略中的任何一種,ossutil將根據策略判斷是否進行上傳/下載/拷貝,當遇到目標端的檔案已存在,也不會詢問使用者是否進行替換操作,此時–force選項不再生效;
  • 由於讀寫snapshot資訊需要額外開銷,當要批量上傳的檔案數比較少或網路狀況比較好或有其他使用者操作相同object時,並不建議使用該選項,可以使用–update選項來增量上傳。


相關文章