来自boto3或boto api的两个不同帐户/连接之间的桶/密钥的并行副本

时间:2017-01-19 10:26:36

标签: python amazon-s3 boto boto3

我想使用boto3 api从两个不同帐户之间的存储桶中复制密钥。 在boto3中,我执行了以下代码,副本工作

source =  boto3.client('s3')
destination = boto3.client('s3')
destination.put_object(source.get_object(Bucket='bucket', Key='key'))

基本上我从GET获取数据并用另一个帐户中的PUT粘贴它。

在boto api上的类似行中,我做了以下

source = S3Connection()
source_bucket = source.get_bucket('bucket')
source_key = Key(source_bucket, key_name)

destination = S3Connection()
destination_bucket = destination.get_bucket('bucket')
dist_key = Key(destination_bucket, source_key.key)
dist_key.set_contents_from_string(source_key.get_contents_as_string())

上述代码实现了复制任何类型数据的目的。 但速度真的很慢。我大约需要15-20秒来复制1GB的数据。我必须复制100GB以上。 我尝试了python mutithreading,其中每个线程都执行复制操作。性能很差,因为复制1GB需要30秒。我怀疑GIL可能是这里的问题。 我做了多处理,我得到了与单个进程相同的结果,即1GB文件的15-20秒。

我使用的是具有48核和128GB RAM的高端服务器。我环境中的网络速度是10GBPS。 大多数搜索结果都说明了在同一帐户中的存储桶之间复制数据,而不是跨帐户复制数据。任何人都可以在这里指导我。我的方法有误吗?有没有人有更好的解决方案?

2 个答案:

答案 0 :(得分:2)

是的,这是错误的做法。

不应该下载该文件。您正在使用AWS基础架构,因此您应该使用有效的AWS后端调用来完成工作。你的方法是浪费资源。

boto3.client.copy将比这更好地完成工作。

此外,您没有描述您要实现的目标(例如,这是某种复制要求吗?)。

因为正确理解您自己的需求,您可能甚至不需要服务器来完成这项工作:S3 Bucket事件触发器,lambda等都可以在没有服务器的情况下执行复制作业。

要在两个不同的AWS账户之间复制文件,您可以查看此链接Copy S3 object between AWS account

注意:

S3是一个适合所有人的巨大虚拟对象存储库,这就是存储桶名称必须是唯一的原因。这也意味着,S3“控制器”可以完成许多类似于文件服务器的花哨工作,例如复制,复制,在后端移动文件,不涉及网络流量。

只要为目标存储桶设置了正确的IAM权限/策略,对象就可以跨存储桶移动而无需额外的服务器。

这几乎与文件服务器类似。用户可以在没有“下载/上传”的情况下相互复制文件,而只需创建一个具有所有写入权限的文件夹,来自另一个用户的文件复制全部在文件服务器中完成,具有最快的原始磁盘I / O性能。 您不需要使用后端S3 copy API的强大实例或高性能网络

您的方法类似于使用相同文件服务器从用户尝试FTP下载文件,这会产生不需要的网络流量。

答案 1 :(得分:1)

您应该查看boto3中的TransferManager。它将以有效的方式自动处理分段上传的线程。有关详细信息,请参阅the docs

基本上你必须使用upload_file方法,而TransferManager将负责其余的工作。

import boto3

# Get the service client
s3 = boto3.client('s3')

# Upload tmp.txt to bucket-name at key-name
s3.upload_file("tmp.txt", "bucket-name", "key-name")