Многокомпонентные загрузки в Amazon S3 с Java

Несколько загрузок в Amazon S3 с Java

1. обзор

В этом руководстве мы увидим, как обрабатывать многокомпонентные загрузки в Amazon S3 с помощью AWS Java SDK.

Simply put, in a multipart upload, we split the content into smaller parts and upload each part individually. При получении все детали собираются заново.

Многокомпонентные загрузки предлагают следующие преимущества:

  • Более высокая пропускная способность - мы можем загружать детали параллельно

  • Более простое восстановление после ошибок - нам нужно повторно загружать только неисправные детали

  • Приостановка и возобновление загрузки - мы можем загружать детали в любой момент времени. Весь процесс может быть приостановлен, а оставшиеся части могут быть загружены позже

Обратите внимание, что при использовании составной загрузкиwith Amazon S3, each part except the last part must be at least 5 MB in size.

2. Maven Зависимости

Прежде чем мы начнем, нам нужно добавить зависимость AWS SDK в наш проект:


    com.amazonaws
    aws-java-sdk
    1.11.290

Чтобы просмотреть последнюю версию, проверьтеMaven Central.

3. Выполнение Multipart Upload

3.1. Создание клиента Amazon S3

Во-первых, нам нужноcreate a client for accessing Amazon S3.. Мы будем использовать для этой целиAmazonS3ClientBuilder:

AmazonS3 amazonS3 = AmazonS3ClientBuilder
  .standard()
  .withCredentials(new DefaultAWSCredentialsProviderChain())
  .withRegion(Regions.DEFAULT_REGION)
  .build();

Это создает клиента, использующего цепочку поставщиков учетных данных по умолчанию для доступа к учетным данным AWS.

Для получения дополнительных сведений о том, как работает цепочка поставщиков учетных данных по умолчанию, см.the documentation. Если вы используете регион, отличный от региона по умолчанию (US West-2), убедитесь, что вы заменилиRegions.DEFAULT_REGION на этот пользовательский регион.

3.2. Создание TransferManager для управления загрузками

Мы будем использоватьTransferManagerBuilder для создания экземпляраTransferManager.

Этот классprovides simple APIs to manage uploads and downloads with Amazon S3 управляет всеми связанными задачами:

TransferManager tm = TransferManagerBuilder.standard()
  .withS3Client(amazonS3)
  .withMultipartUploadThreshold((long) (5 * 1024 * 1025))
  .build();

Порог загрузки из нескольких частей определяет размер в байтах, выше которого загрузка должна выполняться как загрузка из нескольких частей.

В Amazon S3 установлен минимальный размер части 5 МБ (для частей, отличных от последней части), поэтому мы использовали 5 МБ в качестве порогового значения загрузки из нескольких частей.

3.3. Загрузка объекта

To upload object using TransferManager we simply need to call its upload() function. Это загружает части параллельно:

String bucketName = "example-bucket";
String keyName = "my-picture.jpg";
String file = new File("documents/my-picture.jpg");
Upload upload = tm.upload(bucketName, keyName, file);

TransferManager.upload() возвращает объектUpload. Это может быть использовано для проверки статуса и управления загрузками. Мы сделаем это в следующем разделе.

3.4. Ожидание завершения загрузки

TransferManager.upload() is a non-blocking function; он возвращается немедленно, пока загрузка выполняется в фоновом режиме.

Мы можемuse the returned Upload object to wait for the upload to complete перед выходом из программы:

try {
    upload.waitForCompletion();
} catch (AmazonClientException e) {
    // ...
}

3.5. Отслеживание прогресса загрузки

Отслеживать прогресс загрузки - довольно распространенное требование; мы можем сделать это с помощью экземпляраProgressListener:

ProgressListener progressListener = progressEvent -> System.out.println(
  "Transferred bytes: " + progressEvent.getBytesTransferred());
PutObjectRequest request = new PutObjectRequest(
  bucketName, keyName, file);
request.setGeneralProgressListener(progressListener);
Upload upload = tm.upload(request);

Созданный намиProgressListener просто продолжит выводить количество переданных байтов до завершения загрузки.

3.6. Управление параллелизмом загрузки

По умолчаниюTransferManager использует максимум десять потоков для выполнения многокомпонентной загрузки.

Однако мы можем контролировать это, указавExecutorService при построенииTransferManager:

int maxUploadThreads = 5;
TransferManager tm = TransferManagerBuilder.standard()
  .withS3Client(amazonS3)
  .withMultipartUploadThreshold((long) (5 * 1024 * 1025))
  .withExecutorFactory(() -> Executors.newFixedThreadPool(maxUploadThreads))
  .build();

Здесь мы использовали лямбду для создания реализации оболочкиExecutorFactory и передали ее функцииwithExecutorFactory().

4. Заключение

В этой быстрой статье мы узнали, как выполнять многоэтапную загрузку с помощью AWS SDK для Java, и увидели, как управлять некоторыми аспектами загрузки и отслеживать ее прогресс.

Как всегда, доступен полный код этой статьиover on GitHub.