【问题标题】:Fastest way to sync two Amazon S3 buckets同步两个 Amazon S3 存储桶的最快方法
【发布时间】:2017-01-02 02:46:20
【问题描述】:

我有一个 S3 存储桶,其中包含大约 400 万个文件,总共占用了大约 500GB。我需要将文件同步到一个新的存储桶(实际上更改存储桶的名称就足够了,但由于这是不可能的,我需要创建一个新的存储桶,将文件移到那里,然后删除旧的)。

我正在使用 AWS CLI 的 s3 sync 命令,它可以完成这项工作,但需要很多时间。我想减少时间,以便相关系统停机时间最短

我试图从本地机器和EC2 c4.xlarge 实例运行同步,所用时间没有太大差异。

我注意到,当我使用 --exclude--include 选项将作业分成多个批次并从单独的终端窗口并行运行它们时,所花费的时间可能会有所减少,即

aws s3 sync s3://source-bucket s3://destination-bucket --exclude "*" --include "1?/*" 
aws s3 sync s3://source-bucket s3://destination-bucket --exclude "*" --include "2?/*" 
aws s3 sync s3://source-bucket s3://destination-bucket --exclude "*" --include "3?/*" 
aws s3 sync s3://source-bucket s3://destination-bucket --exclude "*" --include "4?/*" 
aws s3 sync s3://source-bucket s3://destination-bucket --exclude "1?/*" --exclude "2?/*" --exclude "3?/*" --exclude "4?/*"

我还能做些什么来加快同步速度?另一种类型的EC2 实例是否更适合该工作?将作业分成多个批次是个好主意吗?是否有类似“最佳”数量的 sync 进程可以在同一个存储桶上并行运行?

更新

我倾向于在关闭系统之前同步存储桶的策略,进行迁移,然后再次同步存储桶以仅复制同时更改的少量文件。但是,即使在没有差异的存储桶上运行相同的 sync 命令也需要很多时间。

【问题讨论】:

  • 500gig 的数据需要很长时间才能复制,无论您做什么。磁盘只有这么多可用带宽。
  • @MarcB 是的。忘了提到我倾向于的迁移策略是在关闭系统之前同步存储桶。进行切换,然后再次运行同步以仅复制同时更改的最少量文件。看起来sync 命令需要很多时间,即使只是检查文件是否更改 - 即使实际上不需要复制文件。
  • 这 500gig 中有多少个文件?即使只是比较时间戳也会很慢,因为它基本上要求对每个文件进行stat() 操作。不知道同步在后台实际做了什么,但是如果后端系统比较物理字节(以防时间戳没有改变),或者对文件进行哈希处理并比较哈希,你仍然需要读取 2x500gig 的数据来获取这些字节/哈希.
  • 您是否尝试在存储桶上启用加速传输?
  • @error2007s 看看我的更新。即使不进行文件传输,操作也需要很长时间。

标签: amazon-web-services amazon-s3 amazon-ec2 aws-cli


【解决方案1】:

您可以使用 EMR 和 S3-distcp。我必须在两个存储桶之间同步 153 TB,这大约需要 9 天。还要确保存储桶位于同一区域,因为您还会受到数据传输成本的影响。

aws emr add-steps --cluster-id <value> --steps Name="Command Runner",Jar="command-runner.jar",[{"Args":["s3-dist-cp","--s3Endpoint","s3.amazonaws.com","--src","s3://BUCKETNAME","--dest","s3://BUCKETNAME"]}]

http://docs.aws.amazon.com/ElasticMapReduce/latest/DeveloperGuide/UsingEMR_s3distcp.html

http://docs.aws.amazon.com/ElasticMapReduce/latest/ReleaseGuide/emr-commandrunner.html

【讨论】:

    【解决方案2】:

    在不到 90 秒的时间内复制/同步了 160gb 的 40100 个对象

    按照以下步骤操作:

    step1- select the source folder
    step2- under the properties of the source folder choose advance setting
    step3- enable transfer acceleration and get the endpoint 
    

    AWS 配置只需一次(无需每次都重复)

    aws configure set default.region us-east-1 #set it to your default region
    aws configure set default.s3.max_concurrent_requests 2000
    aws configure set default.s3.use_accelerate_endpoint true
    

    选项:-

    --delete : 如果源中不存在此选项,则此选项将删除目标中的文件

    AWS 命令​​同步

    aws s3 sync s3://source-test-1992/foldertobesynced/ s3://destination-test-1992/foldertobesynced/ --delete --endpoint-url http://soucre-test-1992.s3-accelerate.amazonaws.com 
    

    传输加速成本

    https://aws.amazon.com/s3/pricing/#S3_Transfer_Acceleration_pricing

    如果存储桶位于同一区域,他们没有提及定价

    【讨论】:

    • 注意,如果存储桶的名称中包含 .,则传输加速将不起作用。 aws 命令行也会提供一个令人困惑的“:命名的存储桶与 DNS 不兼容”错误,如果它在配置中 (stackoverflow.com/a/41795555/18706)。
    【解决方案3】:

    作为 OP 已经在做的事情的一个变体..
    可以使用aws s3 sync --dryrun

    创建要同步的所有文件的列表
    aws s3 sync s3://source-bucket s3://destination-bucket --dryrun
    # or even
    aws s3 ls s3://source-bucket --recursive
    

    使用要同步的对象列表,将作业拆分为多个aws s3 cp ... 命令。这样一来,“aws cli”就不会只是挂在那里,同时获取同步候选者列表,就像使用 --exclude "*" --include "1?/*" 类型参数启动多个同步作业时那样。

    当所有“复制”作业都完成后,如果对象可能从“源”存储桶中删除,另一次同步可能是值得的,如果对象可能会从“源”存储桶中删除,则可能是 --delete

    如果“源”和“目标”存储桶位于不同区域,可以在开始同步存储桶之前启用cross-region 存储桶复制。

    【讨论】:

    • 我很想知道使用大型数据集执行此命令时的速度:SOURCE_BUCKET="s3://source-bucket"; TARGET_BUCKET="s3://destination-bucket"; aws s3 ls ${SOURCE_BUCKET} --recursive | awk '{print $4}' | xargs -P 64 -I % aws s3 cp ${SOURCE_BUCKET}/% ${TARGET_BUCKET}/%
    【解决方案4】:

    2020 年的新选择:

    我们必须在 S3 存储桶之间移动大约 500 TB(1000 万个文件)的客户端数据。由于我们只有一个月的时间来完成整个项目,而aws sync 的最高速度约为 120 兆字节/秒……我们马上就知道这会很麻烦。

    我首先找到了这个 stackoverflow 线程,但是当我在这里尝试了大多数选项时,它们都不够快。主要问题是它们都依赖于序列项目列表。为了解决这个问题,我想出了一种在没有任何先验知识的情况下并行列出任何存储桶的方法。是的,可以做到!

    开源工具称为 S3P。

    借助 S3P,我们能够使用单个 EC2 实例维持 8 GB/秒的复制速度和 20,000 个项目/秒的列出速度。 (在存储桶所在区域的 EC2 上运行 S3P 会快一点,但在本地机器上运行 S3P 几乎一样快。)

    更多信息:

    或者只是尝试一下:

    # Run in any shell to get command-line help. No installation needed:
    
    npx s3p
    

    (要求 nodejsaws-cli 和有效的 aws-cli 凭据)

    【讨论】:

    • 在我的场景中,我只想同步那些在过去一小时内修改过的文件。 s3p 有没有办法帮助我实现这一目标?
    • 您能否分享一些如何根据上次修改日期进行复制的示例?
    • @ShivamSingh 在您的场景中,根据您的用例,使用S3 same region replication or cross region replication 可能会更好。
    【解决方案5】:

    背景:sync 命令的瓶颈在于列出对象和复制对象。列出对象通常是一个串行操作,但如果您指定前缀,则可以列出对象的子集。这是并行化它的唯一技巧。复制对象可以并行完成。

    不幸的是,aws s3 sync 不进行任何并行化,它甚至不支持按前缀列出,除非前缀以/ 结尾(即,它可以按文件夹列出)。这就是它如此缓慢的原因。

    s3s3mirror(和许多类似的工具)并行复制。我认为它(或任何其他工具)不会并行列出对象,因为这需要先验知识如何命名对象。但是,它确实支持前缀,您可以对字母表中的每个字母(或任何合适的)多次调用它。

    您也可以使用 AWS API 自行滚动。

    最后,如果您在与 S3 存储桶位于同一区域的实例中启动 aws s3 sync 命令本身(以及与此相关的任何工具),它应该会更快一些。

    【讨论】:

      【解决方案6】:

      正如最近(2020 年 5 月)平铺的 AWS 博客文章所述:

      Once 还可以对现有对象使用 S3 复制。这需要联系 AWS 支持以启用此功能:

      客户可以通过联系 AWS 支持将此功能添加到源存储桶,将现有对象复制到同一或不同 AWS 区域中的另一个存储桶

      【讨论】:

        【解决方案7】:

        我使用 Datasync 迁移了 95 TB 的数据。花了大约2天。拥有所有这些用于网络优化、工作并行化的花哨的东西。您甚至可以检查源和目标,以确保所有内容都按预期传输。

        https://aws.amazon.com/datasync/?whats-new-cards.sort-by=item.additionalFields.postDateTime&whats-new-cards.sort-order=desc

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-03-30
          • 1970-01-01
          • 1970-01-01
          • 2021-01-07
          • 2011-03-21
          • 2016-08-25
          • 1970-01-01
          相关资源
          最近更新 更多