如何将所有对象从一个 Amazon S3 存储桶复制到另一个存储桶?

上次更新日期:2022 年 1 月 7 日

我想将所有对象从一个 Amazon Simple Storage Service (Amazon S3) 存储桶复制或移动至另一个存储桶。如何在 S3 存储桶之间迁移对象?

简短描述

如要将对象从一个 S3 存储桶复制到另一个存储桶,请执行如下步骤:

1.    创建新的 S3 存储桶。

2.    安装并配置 AWS 命令行界面 (AWS CLI)。

3.    在 S3 存储桶之间复制对象。

注意:在大型存储桶(包含 1000 万个对象或更多)上使用 aws s3 lsaws s3 sync 命令可能会很耗时,从而导致超时。如果您因存储桶较大而遇到超时,请考虑使用 Amazon CloudWatch 指标计算存储桶中对象的大小和数量。此外,请考虑使用 S3 分批操作来复制对象。

4.    验证对象是否已复制。

5.    将现有 API 调用更新为目标存储桶的名称。

在开始之前,请考虑以下事项:

解决方法

创建新的 S3 存储桶

1.    打开 Amazon S3 控制台

2.    选择创建存储桶

3.    为您的新存储桶选择一个符合 DNS 标准的名称

4.    选择您的 AWS 区域。

提示:为避免跨区域流量导致的性能问题,请在源存储桶所在的相同区域中创建目标存储桶。

5.    或者,选择从现有存储桶复制设置,以复制源存储桶的配置。

安装和配置 AWS CLI

1.    安装 AWS CLI

2.    运行以下命令,配置 AWS CLI:

aws configure

注意:如果在运行 AWS CLI 命令时遇到错误,请确保您使用的是最新版本的 AWS CLI

3.    输入您的访问密钥(访问密钥 ID 和秘密访问密钥)

4.    按 Enter 跳过默认区域和默认输出选项。有关 Amazon S3 区域参数的更多信息,请参阅 AWS 服务终端节点

注意:AWS CLI 输出为 JSON、文本或表,但并非所有命令都支持每种类型的输出。有关更多信息,请参阅控制 AWS CLI 的命令输出

在 S3 存储桶之间复制对象

1.    如果您将 S3 对象归档在 Amazon Simple Storage Service Glacier 存储类中,请还原对象

2.    使用 AWS CLI 运行以下 sync 命令,在源存储桶和目标存储桶之间复制对象:

aws s3 sync s3://DOC-EXAMPLE-BUCKET-SOURCE s3://DOC-EXAMPLE-BUCKET-TARGET

注意:请更新 sync 命令以包含源存储桶名称和目标存储桶的名称。

sync 命令使用 CopyObject API 在 S3 存储桶之间复制对象。sync 命令会列出源存储桶和目标存储桶,以识别出位于源存储桶而没有位于目标存储桶中的对象。该命令还会识别出源存储桶中 LastModified 日期与目标存储桶中不同的对象。对版本化存储桶使用 sync 命令时,将仅复制对象的当前版本,不会复制早期版本。原定设置下,此行为会保留对象元数据。

如果源存储桶启用了访问控制列表 (ACL),则不会将这些 ACL 复制到目标存储桶。无论目标存储桶上是否启用了 ACL,都是如此。如果源存储桶和目标存储桶都启用了 ACL,则目标对象 ACL 将向执行复制的账户授予 FULL_CONTROL。如果操作失败,您可以重新运行 sync 命令,但不复制先前所复制的对象。要解决 sync 操作的问题,请参阅为何无法在两个 Amazon S3 存储桶之间复制对象?

3.    (可选)如果遇到超时,请使用 cloudwatch get-metric-statistics 命令来计算存储桶中的对象数:

$ aws cloudwatch get-metric-statistics --namespace AWS/S3 --metric-name NumberOfObjects --dimensions Name=BucketName,Value=DOC-EXAMPLE-BUCKET-SOURCE Name=StorageType,Value=AllStorageTypes --start-time 2021-05-11T00:00 --end-time 2021-05-11T00:10 --period 600 --statistic Average --output json

4.    (可选)如果遇到超时,请使用 cloudwatch get-metric-statistics 命令来检索存储桶大小:

$ aws cloudwatch get-metric-statistics --namespace AWS/S3 --metric-name BucketSizeBytes --dimensions Name=BucketName,Value=DOC-EXAMPLE-BUCKET-SOURCE Name=StorageType,Value=StandardStorage --start-time 2021-05-11T00:00 --end-time 2021-05-11T00:10 --period 3600 --statistics Average --unit Bytes --output json

注意:列表调用可能非常耗时,从而导致命令超时。对于较大的存储桶,请考虑使用 Amazon CloudWatch 指标来计算存储桶的大小和对象总数。但是,由于 Amazon CloudWatch 指标每天仅提取一次,因此报告的对象计数和存储桶大小可能与 list 命令结果不同。

验证对象是否已复制

1.    运行以下命令,验证源存储桶和目标存储桶的内容:

aws s3 ls --recursive s3://DOC-EXAMPLE-BUCKET-SOURCE --summarize > bucket-contents-source.txt
        
aws s3 ls --recursive s3://DOC-EXAMPLE-BUCKET-TARGET --summarize > bucket-contents-target.txt

注意:请更新 list 命令以包含源存储桶名称和目标存储桶的名称。

2.    使用保存到 AWS CLI 目录文件中的输出,比较源存储桶和目标存储桶中的对象。请参见以下示例输出:

$ aws s3 ls --recursive s3://DOC-EXAMPLE-BUCKET --summarize
2017-11-20 21:17:39      15362 s3logo.png

  Total Objects: 1        Total Size: 15362

将现有 API 调用更新为目标存储桶的名称

更新任何现有的应用程序或工作负载,确保它们使用目标存储桶名称。如果您经常进行写入操作,您可能需要运行 sync命令来解决源存储桶和目标存储桶之间的差异。