我想使用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。 大多数搜索结果都说明了在同一帐户中的存储桶之间复制数据,而不是跨帐户复制数据。任何人都可以在这里指导我。我的方法有误吗?有没有人有更好的解决方案?
答案 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")