【问题标题】:Fastest way to copy S3 files without exact sync无需精确同步即可复制 S3 文件的最快方法
【发布时间】:2020-01-22 11:51:33
【问题描述】:

我有一个包含许多对象的 S3 存储桶,想将它们复制到另一个 S3 存储桶。这不是直接同步,因为有几个要求:

  • 我想简化对象键,以便将/images/all/abcdef.png 复制到/images/abcdef.png(去掉/all
  • 并非所有文件都将被复制。对象键都列在文件中(每行一个键),因为不应复制许多旧键。

使用s3 命令行工具运行它非常慢。我使用了以下脚本:

#!/bin/bash
while read key; do
  newkey=$(echo $key | sed 's/all\///g')
  aws s3 cp s3://oldbucket/images/$key s3://newbucket/images/$newkey
done < $keys

每个文件需要一两秒钟,因此复制所有文件需要很多天(超过 100 万个对象)。注意我是从外部服务器而不是 AWS 机器运行它,尽管物理上很接近(Linode New Jersey 到 AWS US East 1)。这些对象是从大约 30KB 到 3MB 的图像。

我尝试拆分密钥文件并并行运行,但似乎并没有改变速度,不知道为什么。我也无法添加 S3 快速传输选项,因为原始存储桶有一个“。”在其中(S3 限制)。我想知道是否有更快的方法来做到这一点。

【问题讨论】:

  • 您从哪里运行复制命令?它是否来自与存储桶位于同一区域的 Amazon EC2 实例?两个桶是否在同一个区域?物体的典型尺寸是多少? (随时编辑您的问题以添加这些详细信息。)
  • 谢谢,更新了详细信息。
  • 顺便说一句,我希望你能澄清s3 cp 的运作方式,因为我的印象是它只是推动对象而不下载和上传它们。在这种情况下,同步命令可能更有效,因为我很确定它只是在数据中心内复制,但同步不会处理密钥重命名。

标签: amazon-web-services amazon-s3


【解决方案1】:

S3P 可能是目前(2020 年)复制 S3 文件的最快方式。我的速度一直保持在 8GB/秒

(免责声明:我写的。)

任意密钥重写

除了速度快之外,S3P 还特别适合您的任务。 S3P 允许您提供用 JavaScript 编写的任意密钥重写规则。例如,要从密钥中删除“/all/”,您可以执行以下操作:

npx s3p cp \
  --bucket my-bucket\
  --to-bucket my-to-bucket\
  --to-key "js:(key) => key.replace('/all/', '/')"

为什么 S3P 这么快?

我发现的每个工具都被它们按顺序列出 S3 存储桶的事实所阻碍——请求 1000 个项目,等待,再请求下一个 1000 个项目。我找到了一种使用 S3 API 来并行化列表并显着加速任何涉及列出大量文件的 S3 操作的方法。

易于尝试

如果您安装了 Node.js,您可以轻松试用 s3p,只需打开终端并运行以下命令即可获得命令列表:

npx s3p 

注意:尽管您可以在本地机器上运行它,而且速度仍然非常快,但您将在与 S3 存储桶相同的区域(例如 m5.xlarge)中使用大小合适的 EC2 实例获得最佳性能。

【讨论】:

    【解决方案2】:

    aws s3 cp 命令使用 AWS CLI 中的一些特殊代码来确定对象被复制到的位置。然后它发出正常的 Amazon S3 API 调用来复制实际数据:

    • 如果源和目标都是 S3 桶,它使用CopyObject() 告诉 S3 直接在桶之间复制对象(无需下载/上传)
    • 如果源是本地计算机,目标是 S3 存储桶,则使用 PutObject()
    • 如果源是 S3 存储桶,目标是本地计算机,则使用 GetObject()

    aws s3 sync 命令的作用类似(但首先比较源/目标文件)。

    更接近到 Amazon S3 端点(例如从同一区域的 Amazon EC2 实例运行命令)将最大限度地减少网络开销,可能使对象复制更有效。

    parallel 运行命令肯定会让事情变得更快,因为 S3 可以并行复制文件。我经常打开一个 EC2 实例的两个终端窗口,并在每个窗口中发出命令。它们彼此独立运行,因此应该大大加快速度。 (如果正在上传或下载对象,则不一定是这种情况,因为存在网络吞吐量限制。但是,由于您的脚本只是发出 Copy 命令,这无关紧要。)

    替代方案:使用aws s3 mv

    如果您想移动对象(而不仅仅是复制它们),您可以使用aws s3 mv。它实际上对原始文件执行CopyObject(),然后执行DeleteObject()

    【讨论】:

      【解决方案3】:

      约翰的回答非常完整。我只是为您的任务添加一个代码示例,以便与多个工作人员(使用 GNU 并行)并行运行得更快。

      #!/bin/bash
      while read key; do
        newkey=$(echo $key | sed 's/all\///g')
        echo aws s3 cp "s3://oldbucket/images/$key" "s3://newbucket/images/$newkey"
      done < $keys > jobs.txt
      
      workers=30
      parallel -j $workers < jobs.txt
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-12
        • 2017-01-02
        • 2017-06-29
        • 2021-07-24
        • 1970-01-01
        • 1970-01-01
        • 2012-07-02
        相关资源
        最近更新 更多