BOS MultipleUpload
小****子 · 小****子 发布于2015-12-28 16:11 浏览:2459 回复:2

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

aws的s3是直接将multiple upload作为一个函数接口直接提供给开发者,而BOS和阿里的OSS都需要自己实现那三步:

下面详细说明一下这三步,客户端和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 listpickle.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。

接下来我们模拟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了:

这两段代码所在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

点赞  ( 0 )
收藏
评论(2)
共2条回复 最后由d****s回复于2015-12-31 14:40
#2高****师回复于2015-12-29 16:10:09

好厉害,崇拜

0
#3d****s回复于2015-12-31 14:40:51

高手在民间!赞楼主!!!

0
TOP