Перейти к основному содержимому

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

· 4 мин. чтения

1. Обзор

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

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

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

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

Обратите внимание, что при использовании многокомпонентной загрузки с Amazon S3 каждая часть, кроме последней, должна иметь размер не менее 5 МБ.

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

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

<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.290</version>
</dependency>

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

3. Выполнение многокомпонентной загрузки

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

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

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

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

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

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

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

Этот класс предоставляет простые API для управления загрузками и скачиваниями с помощью Amazon S3 и управляет всеми связанными задачами:

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

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

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

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

Чтобы загрузить объект с помощью TransferManager , нам просто нужно вызвать его функцию upload() . Это загружает части параллельно:

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

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

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

TransferManager.upload() — неблокирующая функция ; он возвращается немедленно, пока загрузка выполняется в фоновом режиме.

Мы можем использовать возвращенный объект Upload , чтобы дождаться завершения загрузки перед выходом из программы:

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, и увидели, как управлять некоторыми аспектами загрузки и отслеживать ее ход.

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