美文网首页
BOS MultipleUpload

BOS MultipleUpload

作者: tanxiniao | 来源:发表于2015-12-28 16:06 被阅读0次

    最近终于有时间写一点关于三步上传的东东了,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

    相关文章

      网友评论

          本文标题:BOS MultipleUpload

          本文链接:https://www.haomeiwen.com/subject/nvvphttx.html