【发布时间】:2019-05-24 08:01:05
【问题描述】:
我的 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
【问题讨论】:
-
两个存储桶是否在同一个 AWS 账户中?
-
您是否尝试过简单地使用
CopyObject()方法?它复制一个对象,包括在桶之间,而不需要下载/上传。只要您有权使用与源对象关联的 KMS 密钥,它就可以读取该对象。然后,您将为目标对象指定 KMS 密钥。 -
我的两个bucket都在不同的账户和不同的地区。我无法使用相同的 s3 客户端复制它。
标签: amazon-web-services amazon-s3 aws-lambda