【问题标题】:How can I copy files bigger than 5 GB in Amazon S3?如何在 Amazon S3 中复制大于 5 GB 的文件?
【发布时间】:2012-05-08 12:21:47
【问题描述】:

Amazon S3 REST API 文档说,在 PUT 操作中上传的大小限制为 5gb。大于该大小的文件必须使用 multipart 上传。很好。

但是,我本质上需要的是重命名可能比这更大的文件。据我所知,没有重命名或移动操作,因此我必须将文件复制到新位置并删除旧位置。大于 5gb 的文件究竟是如何完成的?我必须从存储桶到自身进行分段上传吗?在这种情况下,如何将文件分成几部分?

从阅读 boto 的源代码来看,对于大于 5gb 的文件,它似乎不会自动执行类似的操作。有没有我错过的内置支持?

【问题讨论】:

  • 请注意,现在使用标准resource copy -- s3.meta.client.copy(copy_source, 'otherbucket', 'otherkey') 如果文件大于 5GB,则自动使用分段上传

标签: python amazon-s3 boto


【解决方案1】:

据我所知,没有重命名或移动操作,因此我有 将文件复制到新位置并删除旧位置。

没错,对于小于 5 GB 的对象/文件,通过 PUT Object - Copy 操作,然后是 DELETE Object 操作(当然,boto 支持这两种操作,请参阅 @ 987654324@和delete_key()):

PUT 操作的这个实现创建了一个对象的副本 已存储在 Amazon S3 中。一个 PUT 复制操作是一样的 就像执行 GET 然后执行 PUT。添加请求标头, x-amz-copy-source,使 PUT 操作将源对象复制到 目标存储桶。

但是,对于大于 5 GB 的对象/文件,这确实是不可能的:

注意
[...] 您可以在单个原子中创建最大 5 GB 的对象副本 使用此 API 进行操作。 但是,对于复制大于 5 GB,您必须使用分段上传 API。对于概念 信息[...],转到Uploading Objects Using Multipart Upload [...] [强调我的]

同时,Boto 也通过copy_part_from_key() 方法支持这一点;不幸的是,在各自的pull request #425 (allow for multi-part copy commands) 之外没有记录所需的方法(虽然我自己还没有尝试过):

import boto
s3 = boto.connect_s3('access', 'secret')
b = s3.get_bucket('destination_bucket')
mp = b.initiate_multipart_upload('tmp/large-copy-test.mp4')
mp.copy_part_from_key('source_bucket', 'path/to/source/key', 1, 0, 999999999)
mp.copy_part_from_key('source_bucket', 'path/to/source/key', 2, 1000000000, 1999999999)
mp.copy_part_from_key('source_bucket', 'path/to/source/key', 3, 2000000000, 2999999999)
mp.copy_part_from_key('source_bucket', 'path/to/source/key', 4, 3000000000, 3999999999)
mp.copy_part_from_key('source_bucket', 'path/to/source/key', 5, 4000000000, 4999999999)
mp.copy_part_from_key('source_bucket', 'path/to/source/key', 6, 5000000000, 5500345712)
mp.complete_upload()

您可能希望研究有关如何最终在 Java 或 .NET 中实现此目的的相应示例,这可能会提供对一般方法的更多见解,请参阅Copying Objects Using the Multipart Upload API

祝你好运!


附录

请注意以下一般复制的特殊性,很容易被忽视:

复制对象时,可以保留大部分元数据 (默认)或指定新的元数据。 但是,ACL 不会被保留 并为发出请求的用户设置为私有。覆盖 默认 ACL 设置,使用 x-amz-acl 标头指定新的 ACL 生成复制请求时。有关更多信息,请参阅 Amazon S3 ACL。 [强调我的]

【讨论】:

【解决方案2】:

以上内容非常接近工作,不幸的是应该以mp.complete_upload()结束 而不是拼写错误upload_complete()!

我在此处添加了一个工作 boto s3 多部分复制脚本,基于 AWS Java 示例并使用超过 5 GiB 的文件进行了测试:

https://gist.github.com/joshuadfranklin/5130355

【讨论】:

    【解决方案3】:

    我发现这种方法可以上传大于 5gigs 的文件,并将其修改为与 Boto 复制程序一起使用。 这是原文:http://boto.cloudhackers.com/en/latest/s3_tut.html

    import math
    from boto.s3.connection import S3Connection
    from boto.exception import S3ResponseError
    
    
    conn = S3Connection(host=[your_host], aws_access_key_id=[your_access_key],
                        aws_secret_access_key=[your_secret_access_key])
    
    from_bucket = conn.get_bucket('your_from_bucket_name')
    key = from_bucket.lookup('my_key_name')
    dest_bucket = conn.get_bucket('your_to_bucket_name')
    
    total_bytes = key.size
    bytes_per_chunk = 500000000
    
    chunks_count = int(math.ceil(total_bytes/float(bytes_per_chunk)))
    file_upload = dest_bucket.initiate_multipart_upload(key.name)
    for i in range(chunks_count):
        offset = i * bytes_per_chunk
        remaining_bytes = total_bytes - offset
        print(str(remaining_bytes))
        next_byte_chunk = min([bytes_per_chunk, remaining_bytes])
        part_number = i + 1
        file_upload.copy_part_from_key(dest_bucket.name, key.name, part_number,
                                       offset, offset + next_byte_chunk - 1)
    file_upload.complete_upload()
    

    【讨论】:

    • boto3 之前的版本在处理分段上传方面确实很糟糕。从版本 3 开始,这更容易。感谢您的样品,拯救了我的一天。
    【解决方案4】:

    现在标准的.copy 方法将对大于 5gb 的文件执行分段上传。 Official Docs

    import boto3
    s3 = boto3.resource('s3')
    copy_source = {
        'Bucket': 'mybucket',
        'Key': 'mykey'
    }
    s3.meta.client.copy(copy_source, 'otherbucket', 'otherkey')
    

    【讨论】:

    猜你喜欢
    • 2019-02-16
    • 2015-06-14
    • 2013-01-14
    • 2014-12-31
    • 2012-07-27
    • 2018-06-08
    • 2012-07-31
    • 2011-09-27
    • 2013-08-15
    相关资源
    最近更新 更多