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

Mat*_*ell 85 amazon-s3

我想每天将生产桶中的一些文件复制到开发桶中.

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

因为我想要的文件在文件夹结构中是如此之深,所以去每个文件夹并复制/粘贴都太费时了.

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

Ste*_*pel 104

更新

正如alberge(+1)所指出的,现在卓越的AWS命令行界面提供了最通用的方法来与(几乎)所有AWS交互 - 它同时涵盖了大多数服务的API,并且还具有更高级别的S3命令来处理您的具体用例,请参阅S3AWS CLI参考:

  • sync - 同步目录和S3前缀.示例2涵盖了您的用(使用更细粒度的用法--exclude,--include并且还可以使用前缀处理等):

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

    aws s3 sync s3://from_my_bucket s3://to_my_other_bucket
    
    Run Code Online (Sandbox Code Playgroud)

为了完整起见,我将提到通过s3api子命令仍然可以使用较低级别的S3命令,这将允许在最终采用其更高级别功能之前将任何基于SDK的解决方案直接转换到AWS CLI.


初步答复

在S3存储桶之间移动文件可以通过PUT对象 - 复制API(后跟DELETE对象)来实现:

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

可用的所有现有AWS开发工具包都有相应的示例,请参阅在单个操作中复制对象.当然,基于脚本的解决方案在这里显然是首选,因此使用AWS SDK for Ruby复制对象可能是一个很好的起点; 如果您更喜欢Python,那么同样可以通过boto实现,当然,请参阅copy_key()boto的S3 API文档中的方法.

PUT Object只复制文件,因此您需要DELETE Object在成功复制操作后仍然显式删除文件,但是一旦处理存储桶和文件名的整个脚本到位,这将只是另外几行(也有相应的示例) ,参见例如每个请求删除一个对象).

  • @MattDell 你能在这个问题上添加 .NET 答案吗? (2认同)
  • 糟糕的是,亚马逊并不清楚复制命令是否成功,因此操作后的删除似乎很危险。 (2认同)

A B*_*A B 65

新的官方AWS CLI本身支持大部分功能s3cmd.我之前一直在使用s3cmd或者使用ruby AWS SDK来做这样的事情,但官方CLI对此非常有用.

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

aws s3 sync s3://oldbucket s3://newbucket
Run Code Online (Sandbox Code Playgroud)

  • 这应该被投票到列表的顶部.这是在所有这些答案中同步存储桶和最新版本的正确方法. (4认同)
  • 跨区域复制`aws s3 sync s3:// my-bucket-in-eu-west1 s3:// my-bucket-in-eu-central1 --source-region = eu-west-1 --region = eu-中央1` (3认同)

sgi*_*eno 28

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

s3cmd cp --recursive s3://bucket1/directory1 s3://bucket2/directory1
s3cmd mv --recursive s3://bucket1/directory1 s3://bucket2/directory1
Run Code Online (Sandbox Code Playgroud)


Jam*_*mes 24

我花了几天时间编写自己的自定义工具来并行化所需的副本,但之后我遇到了有关如何获取AWS S3 CLI sync命令以使大量并行化同步存储桶的文档.以下命令将告诉AWS CLI使用1,000个线程来执行作业(每个小文件或多部分副本的一部分)并预测100,000个作业:

aws configure set default.s3.max_concurrent_requests 1000
aws configure set default.s3.max_queue_size 100000
Run Code Online (Sandbox Code Playgroud)

运行这些后,您可以使用simple sync命令,如下所示:

aws s3 sync s3://source-bucket/source-path s3://destination-bucket/destination-path
Run Code Online (Sandbox Code Playgroud)

在m4.xlarge机器上(在AWS中 - 4核,16GB RAM),对于我的情况(3-50GB文件),同步/复制速度从大约9.5MiB/s到700 + MiB/s,速度提高了超过默认配置70倍.

更新:请注意,多年来S3CMD已经更新,现在这些更改仅在您处理大量小文件时才有效.另请注意,Windows上的S3CMD(仅限Windows)严重限制了整体吞吐量,无论您使用何种实例大小或设置,每个进程只能达到约3Gbps.其他系统如S5CMD也有同样的问题.我已经和S3团队讨论了这个问题,他们正在研究它.

  • S5Cmd (https://github.com/peakgames/s5cmd) 是 AWS 支持人员用于实现最大吞吐量的实用程序。实例大小确实有很大的不同。新的 c5n 系列在网络方面非常具有成本效益,并且一直达到惊人的 100Gbps。 (2认同)

Mat*_*ell 13

.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);
    }
}
Run Code Online (Sandbox Code Playgroud)

与客户是一样的

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

可能有更好的方法,但它只是我写的一些快速代码来传输一些文件.

  • 凭证用于执行复制命令.这些单个凭据需要在源/目标存储桶中具有适当的读/写权限.要在帐户之间进行复制,您需要使用存储桶策略以允许从其他帐户的凭据访问存储桶. (2认同)

dk.*_*dk. 9

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

s3cmd cp -r s3://productionbucket/feed/feedname/date s3://developmentbucket/feed/feedname
Run Code Online (Sandbox Code Playgroud)

  • "服务器端"问题是有效的.s3cmd传输是否将所有数据分流到客户端,还是直接S3到S3传输?如果是前者,最好在AWS云中运行此操作以避免外部WAN传输. (3认同)

lon*_*ony 9

对我来说,以下命令才有效:

aws s3 mv s3://bucket/data s3://bucket/old_data --recursive
Run Code Online (Sandbox Code Playgroud)

  • 简单而直接的解决方案...为什么要使用 3rd 方工具或解决方法来完成如此简单的任务,而这可以通过 aws cli 完成?! (2认同)

ban*_*tic 7

这是执行此操作的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
Run Code Online (Sandbox Code Playgroud)


Jus*_*man 5

实际上,到目前为止,我只使用AWS s3界面中的复制+粘贴操作.只需导航到要复制的文件,单击"操作" - >"复制",然后导航到目标存储桶和"操作" - >"粘贴"

它可以非常快速地传输文件,它似乎是一个不太复杂的解决方案,不需要任何编程,或者像这样的顶级解决方案.