Самый быстрый способ сделать копию S3 из одного ведра в другое - PullRequest
0 голосов
/ 23 мая 2019

У меня есть файл, который зашифрован в ключе KMS1 в моем ведре1.Мне нужно перенести его в bucket2 и зашифровать его с помощью ключа KMS2.Первоначально я использовал GetObject и PutObject API.Но это занимает много времени для больших файлов (5 ГБ и более).Также я выполняю эту задачу на лямбде, поэтому время ожидания составляет 15 минут.

Я пытался использовать API загрузки TransferManager, но для этого требуется файл, и я столкнулся с приведенной ниже ошибкой.Я планировал сделать загрузку из нескольких частей, а затем сделать загрузку из нескольких частей.Насколько я понимаю, из-за моего требования расшифровать мой файл с помощью ключа 1, а затем зашифровать мой файл с помощью ключа 2, я не могу использовать многочастную копию, так как он использует тот же клиент 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

1 Ответ

0 голосов
/ 24 мая 2019

Вы можете использовать метод CopyObject() для копирования объектов между группами, даже если они находятся в разных учетных записях и в разных регионах . Нет необходимости загружать / выгружать объект!

Допустим, вы копируете из Bucket-A в Region-A, который принадлежит Account-A в Bucket-B в Region-B, который принадлежит Account-B.

Есть два способа сделать это:

Метод вытягивания

  • Допустим, есть пользователь IAM (User-B) в Account-B
  • . Добавьте политику Bucket в Bucket-A, которая разрешает User-B to List / Get из корзины * 1035.*
  • Как User-B, отправьте команду CopyObject() в Amazon S3 в Region-B (целевая корзина «вытягивает» объект из источника)

Метод Push

  • Допустим, есть пользователь IAM (User-A) в Account-A
  • Добавьте политику Bucket в Bucket-B, которая разрешает User-A в Перечислите / поместите в корзину
  • Как User-A, отправьте команду CopyObject() в Amazon S3 в Region-B (целевой контейнер «вытягивает» объект из источника) и убедитесь, чтоукажите ACL как bucket-owner-full-control.Это позволяет целевому сегменту (принадлежащему другой учетной записи) «владеть» скопированным объектом.Это важно!

Я предпочитаю метод «тянуть», потому что он не требует дополнительной спецификации Списка контроля доступа (ACL), так как Account-B владеет объектом, который он копирует (в отличие отAccount-A отправка объекта в Account-B).

Если это одноразовое действие, я бы рекомендовал использовать Интерфейс командной строки AWS (CLI) , поскольку он оченьлегко использовать.Однако, если вам нужно, чтобы он запускался чаще, возможно, стоит его кодировать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...