【最佳实践】OSS开源工具ossutil-增量上传

经常碰到内部同学或者外部客户问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选项来增量上传。
上一篇:mysql 导入导出数据库、数据表的方法


下一篇:js017-错误处理与调试