AWS S3在两个存储桶之间复制文件和文件夹

149

我一直在寻找一个工具,可以帮助我将AWS S3存储桶的内容复制到第二个AWS S3存储桶,而不需要先将内容下载到本地文件系统。

我尝试使用AWS S3控制台的复制选项,但结果缺少了一些嵌套的文件。

我尝试使用Transmit应用程序(由Panic提供)。复制命令将文件首先下载到本地系统,然后再上传回第二个存储桶,这相当低效。


考虑增加您的并发请求计数aws configure set default.s3.max_concurrent_requests 200。请参阅此帖子以获取更多详细信息和选项https://dev59.com/Tm445IYBdhLWcg3w3N0f。 - Balmipour
21个回答

222

在S3存储桶之间复制文件

AWS最近发布了一个用于在存储桶之间复制文件的命令行界面。

http://aws.amazon.com/cli/

$ aws s3 sync s3://mybucket-src s3://mybucket-target --exclude *.tmp
..

这将从一个目标存储桶复制到另一个存储桶。

在此处查看文档:S3 CLI文档


在EC2上运行它,大约在5秒内复制了80MB。 - Stew-au
1
正是我所需要的,因为aws-sdk gem没有一次性复制或同步整个存储桶的功能。谢谢! - odigity
这些存储桶可能位于不同的S3区域。我将添加一个答案,展示如何在不同区域的S3存储桶之间进行复制。 - Adam Gawne-Cain
12
注意:如果您首次使用cli工具,则需要运行“ aws configure”并输入您的凭据。 - S..
请注意,AWS提供了两种CLI类型的工具。分别是“AWS CLI”和“AWS Tools for Powershell”。本回答使用“AWS CLI”。不要像我一样安装错误的工具。 - fishjd
显示剩余6条评论

49

您现在可以在S3管理界面上执行此操作。只需进入一个存储桶,选择所有文件夹 操作->复制。然后移动到新的存储桶中 操作->粘贴


4
太棒了!他指的是网页界面。与大多数其他人不同,我可以用iPad完成这个操作。 - Jacob Foshee
2
这个程序随机地遗漏了子文件夹中嵌套的对象——三年过去了,AWS仍然无法修复这样一个基本的BUG! - RunLoop
这是针对同一地区还是所有地区的? - hakkikonu
1
这些问题在亚马逊的任何文档中有记录吗?@RunLoop - davetapley
1
@dukedave 我不知道并且已经有一段时间没有再次测试了,因为我转而通过命令行进行复制,这样可以完美地工作。 - RunLoop
显示剩余5条评论

45

使用aws-sdk宝石的简化示例:

AWS.config(:access_key_id => '...', :secret_access_key => '...')
s3 = AWS::S3.new
s3.buckets['bucket-name'].objects['source-key'].copy_to('target-key')

如果你想在不同的存储桶之间执行复制操作,那么请指定目标存储桶名称:

s3.buckets['bucket-name'].objects['source-key'].copy_to('target-key', :bucket_name => 'target-bucket')

12

在不同区域的存储桶之间复制

$ aws s3 cp s3://src_bucket/file  s3://dst_bucket/file --source-region eu-west-1 --region ap-northeast-1

以上命令将文件从欧洲区域的存储桶(eu-west-1)复制到日本区域(ap-northeast-1)。您可以使用此命令获取存储桶区域的代码名称:

$ aws s3api get-bucket-location --bucket my_bucket

顺便说一下,在S3 Web控制台中使用复制和粘贴很容易,但似乎是从源存储桶下载到浏览器,然后上传到目标存储桶。对我来说,使用“aws s3”更快。


9
最近的 aws-sdk gem 可以实现这个功能,以下是代码示例:
require 'aws-sdk'

AWS.config(
  :access_key_id     => '***',
  :secret_access_key => '***',
  :max_retries       => 10
)

file     = 'test_file.rb'
bucket_0 = {:name => 'bucket_from', :endpoint => 's3-eu-west-1.amazonaws.com'}
bucket_1 = {:name => 'bucket_to',   :endpoint => 's3.amazonaws.com'}

s3_interface_from = AWS::S3.new(:s3_endpoint => bucket_0[:endpoint])
bucket_from       = s3_interface_from.buckets[bucket_0[:name]]
bucket_from.objects[file].write(open(file))

s3_interface_to   = AWS::S3.new(:s3_endpoint => bucket_1[:endpoint])
bucket_to         = s3_interface_to.buckets[bucket_1[:name]]
bucket_to.objects[file].copy_from(file, {:bucket => bucket_from})

更多细节: 如何使用aws-s3 gem在不同存储桶之间复制文件


感谢您展示如何在服务器之间复制。我正在尝试从美国服务器复制到新加坡服务器。 - Arcolye
@Arcolye,AWS新加坡的延迟现在怎么样了?一年前它很慢且不稳定。 - Anatoly

6

我创建了一个Docker可执行文件,用于运行s3s3mirror 工具。这是一个从一个AWS S3存储桶复制和镜像到另一个存储桶的实用工具。

它是线程化的,允许并行COPY,并且非常节省内存,可以成功地完成s3cmd无法完成的任务。

使用方法:

docker run -e AWS_ACCESS_KEY_ID=FOO -e AWS_SECRET_ACCESS_KEY=BAR pmoust/s3s3mirror [OPTIONS] source_bucket[/prefix] dest_bucket[/prefix]

要获取完整选项列表,请尝试:

docker run pmoust/s3s3mirror 

6
我想你现在可能已经找到了一个好的解决方案,但是对于那些遇到这个问题的人(就像我最近一样),我特意制作了一个简单的工具,专门用于以高度并发、CPU和内存效率的方式将一个S3存储桶镜像到另一个存储桶中。
它在Github上以Apache许可证发布,链接为:https://github.com/cobbzilla/s3s3mirror 当您拥有一个非常大的存储桶并且正在寻求最大性能时,它可能值得尝试。
如果您决定尝试,请告诉我您有任何反馈。

我使用s3s3mirror的经验非常好。我能够在m1.small EC2节点上设置它,并在大约2小时内复制了150万个对象。由于我不熟悉Maven和Java,所以设置有点困难,但只需要在Ubuntu上运行几个apt-get命令即可安装所有内容。最后一点提示:如果(像我一样)您担心在重要的s3存储桶上运行未知脚本,请创建一个具有只读访问权限的特殊用户,并使用这些凭据。零意外删除的机会。 - Micah

5

5

从AWS cli https://aws.amazon.com/cli/,您可以执行以下操作:

aws s3 ls - 这将列出所有S3存储桶。

aws cp --recursive s3://<source bucket> s3://<destination bucket> - 这将把文件从一个存储桶复制到另一个存储桶中。

注意*:当创建跨区域复制存储桶时非常有用。通过执行上述操作,您的文件将被全部跟踪,并且对源区域文件的更新将传播到复制的存储桶中。除了文件删除以外的所有内容都会同步。

在进行CRR时,请确保已在存储桶上启用版本控制。


不再适用于v2 CLI,请参见https://dev59.com/iMHqa4cB1Zd3GeqP7czn#71843461。 - Cornelius Roemer

4
如果你正在shell环境下并且想要复制多个文件而不是所有文件: s3cmd cp --recursive s3://BUCKET1/OBJECT1 s3://BUCKET2[/OBJECT2]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接