在S3存储桶之间移动文件的最佳方法是什么?

我想每天从生产桶中复制一些文件到开发桶。

例如:将productionbucket / feed / feedname / date复制到developmentbucket / feed / feedname / date

由于我想要的文件在文件夹结构中非常深,因此去每个文件夹和复制/粘贴都耗费太多时间。

我已经玩过了将驱动器安装到每个存储桶并编写一个windows批处理脚本,但是这非常慢,并且不必要地将所有文件/文件夹下载到本地服务器并重新备份。

更新

正如alberge (+1) 指出的那样 ,现在优秀的AWS命令行界面提供了与AWS(几乎)所有东西进行交互的最通用的方法 – 它同时覆盖了大多数服务的API,还提供了更高级的S3命令来处理请参阅适用于S3的AWS CLI参考 :

  • 同步 – 同步目录和S3前缀。 你的用例被例2所覆盖(更多细粒度的使用--exclude ,– --include和前缀处理等也是可用的):

    以下同步命令通过复制s3对象将指定前缀和存储桶中的对象同步到另一个指定前缀和存储桶中的对象。 […]

     aws s3 sync s3://from_my_bucket s3://to_my_other_bucket 

为了完整起见 ,我会提到S3命令低级别命令也可以通过s3api子命令来使用,这个命令可以直接将任何基于SDK的解决scheme转换到AWS CLI,然后才能最终采用其更高级别的function。


初始答案

在S3桶之间移动文件可以通过PUT Object – Copy API (接着是DELETE Object )来实现:

PUT操作的此实现将创build已存储在Amazon S3中的对象的副本。 PUT复制操作与执行GET然后执行PUT相同。 添加请求头x-amz-copy-source使PUT操作将源对象复制到目标存储桶中。 资源

现有的所有AWS软件开发工具包都有相应的示例,请参见在单个操作中复制对象 。 自然,基于脚本的解决scheme将成为这里的首选,所以使用适用于Ruby的AWS开发工具包复制对象可能是一个很好的起点。 如果你更喜欢Python,那么当然也可以通过boto来实现,参见boto的S3 API文档中的方法copy_key()

PUT Object只复制文件,因此在成功的复制操作之后,仍然需要通过DELETE Object明确地删除一个文件,但是一旦处理完bucket文件名的整个脚本到位,这只是另外几行。各自的例子,请参阅例如每个请求删除一个对象 )。

新的官方AWS CLI本身支持s3cmd大部分function。 我以前一直在使用s3cmd或者AWS开发工具包来做类似的事情,但是官方的CLI很适合这个。

http://docs.aws.amazon.com/cli/latest/reference/s3/sync.html

 aws s3 sync s3://oldbucket s3://newbucket 

要从一个桶移动/复制到另一个桶或同一个桶,我使用s3cmd工具,并正常工作。 例如:

 s3cmd cp --recursive s3://bucket1/directory1 s3://bucket2/directory1 s3cmd mv --recursive s3://bucket1/directory1 s3://bucket2/directory1 

.NET示例请求:

 using (client) { var existingObject = client.ListObjects(requestForExisingFile).S3Objects; if (existingObject.Count == 1) { var requestCopyObject = new CopyObjectRequest() { SourceBucket = BucketNameProd, SourceKey = objectToMerge.Key, DestinationBucket = BucketNameDev, DestinationKey = newKey }; client.CopyObject(requestCopyObject); } } 

与客户是类似的东西

 var config = new AmazonS3Config { CommunicationProtocol = Protocol.HTTP, ServiceURL = "s3-eu-west-1.amazonaws.com" }; var client = AWSClientFactory.CreateAmazonS3Client(AWSAccessKey, AWSSecretAccessKey, config); 

可能有更好的方法,但这只是我写的一些简单的代码来获得一些文件传输。

如果您在AWS中拥有unix主机,则使用s3tools.org中的s3cmd。 设置权限,以便您的密钥可以读取您的开发存储桶。 然后运行:

 s3cmd cp -r s3://productionbucket/feed/feedname/date s3://developmentbucket/feed/feedname 

这是一个ruby类执行此: https : //gist.github.com/4080793

用法示例:

 $ gem install aws-sdk $ irb -r ./bucket_sync_service.rb > from_creds = {aws_access_key_id:"XXX", aws_secret_access_key:"YYY", bucket:"first-bucket"} > to_creds = {aws_access_key_id:"ZZZ", aws_secret_access_key:"AAA", bucket:"first-bucket"} > syncer = BucketSyncService.new(from_creds, to_creds) > syncer.debug = true # log each object > syncer.perform 

我花了好几天的时间编写我自己的定制工具来并行化所需的副本,但之后我遇到了有关如何使AWS S3 CLI同步命令使用大规模并行化同步存储区的文档。 以下命令将通知AWS CLI使用1,000个线程执行作业(每个小文件或多部分副本的一部分)并outlook100,000个作业:

 aws configure set default.s3.max_concurrent_requests 1000 aws configure set default.s3.max_queue_size 100000 

运行这些之后,可以使用简单同步命令,如下所示:

 aws s3 sync s3://source-bucket/source-path s3://destination-bucket/destination-path 

在m4.xlarge的机器上(在AWS-4核心,16GB RAM中),对于我的情况(3-50GB文件),同步/复制速度从9.5Mib / s增加到700 + MiB / s,比默认configuration高70倍。

对于我来说,下面的命令刚刚工作:

 aws s3 mv s3://bucket/data s3://bucket/old_data --recursive 

我们在Snowplow的ETL作业中遇到了这个问题,所以我们将我们的并行文件复制代码(Ruby,build立在Fog之上)提取到它自己的Ruby gem中,叫做Sluice:

https://github.com/snowplow/sluice

Sluice还处理S3文件的删除,移动和下载; 全部并行,如果一个操作失败(它令人惊讶地经常)自动重试。 我希望这是有用的!

实际上,最近我只是在AWS s3界面中使用复制+粘贴操作。 只需导航到您要复制的文件,点击“操作” – >“复制”,然后导航到目标存储桶和“操作” – >“粘贴”

它传输文件相当快,看起来像一个不需要任何编程,或通过顶级解决scheme这样一个不太复杂的解决scheme。

我知道这是一个古老的线程,但对于那些到达那里的人,我的build议是创build一个计划的工作,从生产斗复制内容到开发。

你可以使用如果你使用.NET这篇文章可能会帮助你

http://www.codewithasp.net/2015/03/aws-s3-copy-object-from-one-bucket-or.html