BOS MultipleUpload

最近终于有时间写一点关于三步上传的东东了,mulitiple upload又称三步上传。三步上传主要针对那些网络环境不好(传着传着就断了),或者上传的文件大于5GB,普通的上传方式满足不了的上传。

aws的s3是直接将multiple upload作为一个函数接口直接提供给开发者,而BOS和阿里的OSS都需要自己实现那三步:
1. 初始化multiple uploadID
2. 上传分块
3. 完成上传
下面详细说明一下这三步,客户端和BOS服务器在做什么。

初始化uploadID:
客户端InitMultiUpload,BOS服务器端根据客户端提供的bucket,object等信息生成在Bucket内唯一的Uploadid,并且将Uploadid返回给客户端;

上传分片:
客户端:上传分片,并提供partNumber。
服务器端:服务器端将文件PartData按照Object的逻辑去存储,并检查当前PartNum为接续块或重新上传的块,每个Part上传时的快照信息保存在PartData Object的Meta数据中。返回给客户端已上传数据的MD5信息,以便校验已上传数据的完整性,断点上传支持最新上传的一块数据的错误重新上传;
注意这里:服务器端是给客户端返回每个分片的MD5的。

结束上传:
客户端提交Bucket、Object、Uploadid、PartList给服务器端。服务器检查每一个已上传的PartData Object的Meta并合并最终的SliceList。如正确,则根据收集到的SliceList、UserMeta信息生成Meta数据写入Meta表。删除PartData Object对应的所有Meta数据。(感觉在这里删除了每个分片的MD5)

整个multipleUpload就是这样的一个处理过程,需要注意的是:最后上传的那个文件是没有content-MD5的,这就是为什么我们说三步上传的文件没有MD5的原因。
理论上,如果每个分片返回的md5值都是对的,那最后合成的文件就是完整并且正确的。以后再说这里怎么去验证。

下面这个部分主要是结合实际的python sdk中的代码,讲一下断点续传。(我也不会python哈,写的比较low,诸位轻批)

这里用到一个pickle库,这货的作用就是持久性地保持对象,用这个货来将我断点发生之前的partlist存到文件里。
用法:

import pickle

写入文件:
f = open("dump.txt", "wb")
partList = []  # then add something into list
pickle.dump(partList, f)
f.close()

从文件读取:
f = open("dump.txt", "rb")
partList = pickle.load(f)
f.close()
# do something with partList

用两个代码来演示一下测试思路:第一个代码client.py模拟我初始化分片,并上传分片,在这个过程中,我用键盘作为中断。这段代码我需要打印出中断时的partNumber,left_size, offset,并且将partlist保存在一个文件b里。

第二个代码resume.py根据uploadID将剩下的分片传到bos上,并且读取文件b中的partlist,完成completeUpload。

client.py的大体思路:
初始化upload,生成uploadID:
upload_id = bos_client.initiate_multipart_upload

计算分块:
offset = 0
part_number = 1
part_list = []
while left_size > 0
      进行分片
      ......
     上传part
     bos_client.upload_part_from_file
     
     打印left_size
     打印offset
     #将partlist存储到文件b中:
     f1 = open("./b","wb")
     pickle.dump(part_list,f1)
     f1.close()

演示:
在本该传第28个分片的时候,我键盘中断了这次操作,并且打印了left_size和offset。


1.png

接下来我们模拟resume.py。

resume.py的大体思路:
upload_id = "bf3167c31f96036f63bec1d1d70ace09"
#如果不知道uploadID,可以用listmultipleUpload根据bucket name列出来。
f1 = open("./b","rb")
#将文件b里的数据读出来,赋给part_list
part_list = pickle.load(f1)
f1.close
#将上图中打印出来的数据传给left_size,offset, part_number。
left_size = 501506048
offset = 141557760
part_number = 28
#剩下这一块的处理跟client.py中while的处理一样了。
while:
        *******

最终,执行完毕之后就可以在控制台看到上传成功的object了:

2.png

这两段代码所在github:
https://github.com/tanxiniao/bos/blob/master/client.py
https://github.com/tanxiniao/bos/blob/master/resumable.py
附赠listmultipleUpload的代码:
https://github.com/tanxiniao/bos/blob/master/listmul.py

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,403评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,417评论 25 709
  • 如果不是上有老下有小,我们可以把假期过得非常悠闲,站在假期出游鄙视链的最顶端,傲视奔波劳碌,屏蔽嘈杂纷乱…沉湎自己...
    王小花和mo阅读 3,619评论 4 12
  • 目前教育系统正在执行的教师职称晋级制度的最大特点就是一劳永逸。然而教育事业要想健康发展就必须真正落实按劳分配的劳动...
    田峰阅读 1,690评论 0 0
  • 在现在这个社会、随便整点网络社交工具都能让你今生功成名就、最关键的还得看拍拍拍技术能不能过关?80年代,我们的梦想...
    Hk迪帅阅读 3,895评论 0 2