如何使用 aws java sdk 将文件从一个区域的 S3 存储桶复制到另一个区域?

How to copy files from S3 bucket from one region to another region using aws java sdk?

我们在 AWS 中有两个区域,每个区域都有一个 AWS S3 Bucket。我如何使用 AWS Java SDK 将存储桶中的文件从一个区域复制到另一个区域?

我们无权访问源区域存储桶的凭据,但我们为源区域存储桶中每个文件的源预签名 URL,我们可以使用它下载文件然后使用AWS 上传 URL 将其上传到目标区域存储桶。

下载文件时存在 space 限制,因此我们正在尝试找到一种使用 AWS Java SDK 将文件从一个区域的存储桶复制到另一个区域的方法。这是可以实现的吗?

编辑:

为更清楚起见,两个存储桶都已创建,这是一个持续的过程,将作为我们代码的一部分实施。这不是一次性的 activity.

通常情况下,存储桶之间的复制很容易。 CopyObject()命令可以在bucket之间(甚至是不同地区不同账号的bucket)复制对象,无需download/upload文件

但是,由于您只能通过预签名 URL 访问文件,您需要:

  • 单独下载每个文件
  • 使用 Java
  • 的 AWS SDK 中的 PutObject() 命令将每个文件上传到目标 Amazon S3 存储桶

这最好在源区域或目标区域的 Amazon EC2 实例上完成。

如果源存储桶的所有者可以为您提供 "normal" 访问对象以便您可以使用 CopyObject(),或者如果他们能够复制对象,那就更好了给你的桶。

我建议先探索 S3 cross-region replication 服务。

以编程方式将文件从存储桶复制到存储桶有很多问题:

  • S3 API 速率限制
  • A​​WS 传输数据的成本
  • 托管您的解决方案的 AWS 成本,无论是托管在 EC2、容器还是无服务器中
  • 开发和维护代码库的成本
  • S3 对象元数据呢?是否需要保留元数据?
  • 启用版本控制的 S3 存储桶如何?
the below code copies the file from one region to another region. If the two different region shares same access and secret key

System.setProperty(SDKGlobalConfiguration.DISABLE_CERT_CHECKING_SYSTEM_PROPERTY, "真");

    AmazonS3 s3ClientBuilder = null;
    AmazonS3 s3desClientBuilder = null;
    TransferManager transferManager = null;
    try {

        ClientConfiguration clientCfg = new ClientConfiguration();
        clientCfg.setProtocol(Protocol.HTTPS);
        clientCfg.setSignerOverride("S3SignerType");
        AWSStaticCredentialsProvider credentialProvidor = new AWSStaticCredentialsProvider(
                new BasicAWSCredentials(accessKey, secretKey));

        s3ClientBuilder = AmazonS3ClientBuilder//
                .standard()//
                .withCredentials(credentialProvidor)//
                .withEndpointConfiguration(new EndpointConfiguration(s3Endpoint, region.getName()))//
                .withClientConfiguration(clientCfg)//
                .build();

//列出s3region中的所有bucket名称

        List<Bucket> buckets = s3ClientBuilder.listBuckets();
        System.out.println("Your Amazon S3 buckets are:");
        for (Bucket b : buckets) {
            System.out.println("* " + b.getName());
        }

//列出桶内的object和objectkey

        ListObjectsRequest lor = new ListObjectsRequest()
                .withBucketName(SOURCE_BUCKET_NAME)
                .withPrefix("vivek/20210801");
        ObjectListing objectListing = s3ClientBuilder.listObjects(lor);
        for (S3ObjectSummary summary: objectListing.getObjectSummaries()) {

            SOURCE_KEY=summary.getKey();
            DESTINATION_KEY=SOURCE_KEY

            s3desClientBuilder = AmazonS3ClientBuilder//
                    .standard()//
                    .withCredentials(credentialProvidor)//
                    .withEndpointConfiguration(new EndpointConfiguration(s3desEndpoint, region.getName()))//
                    .withClientConfiguration(clientCfg)//
                    .build();

             transferManager = TransferManagerBuilder.standard()
                    .withS3Client(s3desClientBuilder)
                    .build();

            Copy copy = transferManager.copy(new CopyObjectRequest(SOURCE_BUCKET_NAME, SOURCE_KEY,
                    DESTINATION_BUCKET_NAME, DESTINATION_KEY),
                    s3ClientBuilder, null);
            copy.waitForCopyResult();   
        }
        transferManager.shutdownNow();
        s3ClientBuilder.shutdown();
        s3desClientBuilder.shutdown();