本文共 6362 字,大约阅读时间需要 21 分钟。
经常碰到内部同学或者外部客户问ossutil关于大文件断点续传的问题。本文简单描述下原理并举例说明。
用户可从这里获取ossutil。
官网:
代码:当调用OSS的PutObject来上传较大的文件时,如果上传过程中出现错误,比如网络错误,那么此次上传失败。重试时必须从文件起始位置上传。
针对这种情况,OSS提供了分片上传(Multipart Upload)来达到断点续传的效果。分片上传就是将要上传的文件分成多个数据块(OSS里又称之为Part)来分别上传,上传完成之后再调用OSS的接口将这些Part组合成一个Object。
因此,OSS断点续传适用于以下场合。
详细信息,请参考。
在分片上传的过程中,已经上传的Part的生命周期是永久的,因此很容易可以实现断点续传的功能。
如果分片上传意外失败,可以在重启的时候调用以下接口。
ListMultipartUploads
ListParts
有了上传成功的Part列表,就可以从最后一块成功上传的Part开始继续上传,从而达到断点续传的效果。暂停和恢复上传实现原理也是一样的。
ossutil上传文件时,如果文件大小超过--bigfile-threshold选项指定的大小(默认为100M),ossutil会认为该文件为大文件,并自动使用断点续传策略。
上传至OSS
从OSS下载
在OSS间拷贝
断点续传的重点在于需要本地记录已经上传了多少,还需要上传多少。因此ossutil在本地默认.ossutil_checkpoint目录下创建文件记录本次上传分片信息,并用LevelDB记录哪些分片已经上传成功。
比如,在.ossutil_checkpoint目录下创建如下文件并记录分片信息。具体内容可参考后面的例子。
$ ls .ossutil_checkpoint/Users/tester/ws/test.file.200M---oss:/tempb3/test.file.200M.cp.ossutil_checkpoint/Users/tester/ws/test.file.200M---oss:/tempb3/test.file.200M.cp
本文给出一个上传的例子,下载和拷贝操作方法类似。
# 200M文件上传$ ls -lh test.file.200M-rw-r--r-- 1 zubo.yzb staff 200M 6 11 15:34 test.file.200M# 上传18%时Ctrl+C掉$ ossutil cp test.file.200M oss://tempb3Total num: 1, size: 209,715,200. Dealed num: 0, OK size: 38,456,400, Progress: 18%^C⏎
ls命令加-a选项可参考分片信息。
$ ossutil ls oss://tempb3 -aObject Number is: 0InitiatedTime UploadID ObjectName2018-06-11 15:34:57 +0800 CST 15E03889BFF34823AF47A6F65A8E7B11 oss://tempb3/test.file.200MUploadID Number is: 10.116129(s) elapsed
也可以登录控制台查看分片(碎片)信息。
默认在当前目录下会创建.ossutil_checkpoint目录,并将断点信息写入文件,文件名如上所述。
文件数据定义如下。
type uploadCheckpoint struct { Magic string // magic MD5 string // cp内容的MD5 FilePath string // 本地文件 FileStat cpStat // 文件状态 ObjectKey string // key UploadID string // upload id Parts []cpPart // 本地文件的全部分片}type cpStat struct { Size int64 // 文件大小 LastModified time.Time // 本地文件最后修改时间 MD5 string // 本地文件MD5}type cpPart struct { Chunk FileChunk // 分片 Part UploadPart // 上传完成的分片 IsCompleted bool // upload是否完成}
// FileChunk 文件片定义type FileChunk struct { Number int // 块序号 Offset int64 // 块在文件中的偏移量 Size int64 // 块大小}// UploadPart 上传/拷贝的分片type UploadPart struct { XMLName xml.Name `xml:"Part"` PartNumber int `xml:"PartNumber"` // Part编号 ETag string `xml:"ETag"` // ETag缓存码}
文件内容如下。
{ "FilePath": "test.file.200M", "FileStat": { "LastModified": "2018-06-11T15:34:18+08:00", "MD5": "", "Size": 209715200 }, "MD5": "3Rv7Fx0gbfPLWKOa4OjMew==", "Magic": "FE8BB4EA-B593-4FAC-AD7A-2459A36E2E62", "ObjectKey": "test.file.200M", "Parts": [ { "Chunk": { "Number": 1, =====> 第1个分片 "Offset": 0, "Size": 2563760 =====> 每个分片size为2563760=2503KB }, "IsCompleted": true, =====> 已经成功上传 "Part": { "ETag": "\"EC704FC6D8822194EEC4E68769739BE3\"", =====>已经成功上传的分片有ETag "PartNumber": 1, =====> 第1个分片 "XMLName": { "Local": "", "Space": "" } } },。。。 { "Chunk": { "Number": 15, =====> 第15个分片 "Offset": 35892640, "Size": 2563760 }, "IsCompleted": true, =====> 已经成功上传 "Part": { "ETag": "\"EC704FC6D8822194EEC4E68769739BE3\"", "PartNumber": 15, "XMLName": { "Local": "", "Space": "" } } }, { "Chunk": { "Number": 16, =====> 第16个分片 "Offset": 38456400, "Size": 2563760 }, "IsCompleted": false, =====> 未上传 "Part": { "ETag": "", "PartNumber": 0, "XMLName": { "Local": "", "Space": "" } } },。。。 { "Chunk": { "Number": 82, =====>82个分片 "Offset": 207664560, "Size": 2050640 }, "IsCompleted": false, "Part": { "ETag": "", "PartNumber": 0, "XMLName": { "Local": "", "Space": "" } } } ], "UploadID": "15E03889BFF34823AF47A6F65A8E7B11"}
再次上传直接从断点开始继续,可以观察到progress直接从18%开始,直到结束。
$ ossutil cp test.file.200M oss://tempb3 -fSucceed: Total num: 1, size: 209,715,200. OK num: 1(upload 1 files).11.461563(s) elapsed
如果使用rm命令删除了Uncomplete的Multipart Upload,可能会造成下次cp命令断点续传失败(报错:NoSuchUpload),这种时候如果想要重新上传整个文件,请删除相应的checkpoint文件。
$ ossutil cp test.file.200M oss://tempb3Total num: 1, size: 209,715,200. Dealed num: 0, Transfer size: 0. When error happens.Error: oss: service returned error: StatusCode=404, ErrorCode=NoSuchUpload, ErrorMessage=The specified upload does not exist. The upload ID may be invalid, or the upload may have been aborted or completed., RequestId=5B1E2B177953A44A418E6FD5, File=test.file.200M!Will remove checkpoint dir '.ossutil_checkpoint' automatically. Please try again.⏎
转载地址:http://umybo.baihongyu.com/