我有一个文件,该文件在我的bucket1中用KMS key1加密。我需要将其传输到bucket2并使用KMS key2对其进行加密。我最初使用的是GetObject和PutObject API。但是,较大的文件(5GB及以上)需要花费很长时间。我也在lambda上执行此任务,因此超时为15分钟。
我尝试使用TransferManager下载API,但是它需要一个文件,并且遇到以下错误。我打算进行多部分下载,然后进行多部分上传。根据我的理解,由于需要使用key1解密文件然后使用key2加密文件,我无法使用多份副本,因为它使用了相同的Amazon S3客户端。
TransferManager sourceTransferManager = TransferManagerBuilder
.standard().withS3Client(sourceS3Client).build();
GetObjectRequest getObjectRequest = new GetObjectRequest(srcBucket, srcKey);
File modelFile = File.createTempFile("BigFile", "gz");
logger.log("Starting download");
Download download = sourceTransferManager.download(getObjectRequest, modelFile);
download.waitForCompletion();
sourceTransferManager.shutdownNow();
logger.log("Finishing download");
logger.log("Downloaded the object, let's upload it");
//For a decrypted object, the content length in metadata still has the encrypted length
//Set the content length to the unencrypted-data-length
PutObjectRequest putObjectRequest = new PutObjectRequest(destS3Uri.getBucket(), destS3Uri.getKey(), modelFile);
transferManager = TransferManagerBuilder
.standard()
.withS3Client(destS3Client)
.build();
Upload upload = transferManager.upload(putObjectRequest);```
aused by: com.amazonaws.SdkClientException: Unable to store object contents to disk: No space left on device
at com.amazonaws.services.s3.internal.ServiceUtils.downloadToFile(ServiceUtils.java:314)
at com.amazonaws.services.s3.transfer.DownloadCallable.retryableDownloadS3ObjectToFile(DownloadCallable.java:275)
at com.amazonaws.services.s3.transfer.DownloadCallable.downloadAsSingleObject(DownloadCallable.java:92)
at com.amazonaws.services.s3.transfer.internal.AbstractDownloadCallable.call(AbstractDownloadCallable.java:102)
at com.amazonaws.services.s3.transfer.internal.AbstractDownloadCallable.call(AbstractDownloadCallable.java:40)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.IOException: No space left on device
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:326)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:122)
at com.amazonaws.services.s3.internal.ServiceUtils.downloadToFile(ServiceUtils.java:309)
... 8 more
答案 0 :(得分:0)
即使存储桶位于不同帐户和不同区域中,也可以使用CopyObject()
方法在存储桶之间复制对象。 无需下载/上传对象!
假设您要从Bucket-A
的{{1}}中的Region-A
复制到Account-A
的{{1}}中的Bucket-B
。 / p>
有两种方法可以做到:
拉方法
Region-B
中有一个IAM用户(Account-B
)User-B
添加存储桶策略,该策略允许Account-B
从存储桶列出/获取 Bucket-A
,将User-B
中的User-B
命令发送到Amazon S3(目标存储桶从源“拉”对象)推送方法
CopyObject()
中有一个IAM用户(Region-B
)User-A
添加一个存储桶策略,该策略允许Account-A
List / Put 到存储桶Bucket-B
,将User-A
中的User-A
命令发送到Amazon S3(目标存储桶从源“拉”对象),并确保指定 ACL 作为CopyObject()
。这样,目标存储桶(由其他帐户拥有)可以“拥有”复制的对象。这很重要!我更喜欢'pull'方法,因为它不需要访问控制列表(ACL)的其他规范,因为Region-B
拥有它复制的对象(与bucket-owner-full-control
发送对象相反)到Account-B
)。
如果这是一次性活动,我建议使用AWS Command-Line Interface (CLI),因为它非常易于使用。但是,如果您需要使其运行更多,则可能需要对其进行编码。