Составная (multipart) загрузка объекта
При загрузке объекта в бакет Object Storage может произойти сетевой сбой, в результате которого загрузка прервется и файл придется загружать заново. Чем больше размер загружаемого файла, тем дольше длится загрузка и выше риск возникновения сетевых ошибок.
Поэтому большие файлы эффективнее загружать в бакет частями с помощью составной (multipart) загрузки. В случае сетевого сбоя при загрузке части файла повторно загружать потребуется только одну эту составную часть, а не весь файл.
Чтобы загрузить в бакет объект по частям:
Разбейте исходный файл на части
На вашем компьютере разбейте исходный файл на части нужных размеров. Например, это можно сделать с помощью команды split:
split -b 100M ./video.mp4 part.
Где:
-
100M— размер частей, на которые разбивается файл. В примере задан размер100 МБ.Суффикс
Mозначает, что размер задан в мегабайтах. Вы также можете использовать суффиксыKиG, чтобы задать размер в килобайтах и гигабайтах соответственно. -
./video.mp4— путь к исходному файлу, который нужно разбить на части, чтобы потом загрузить в бакет. -
part.— префикс имен файлов, которые будут присваиваться частям.
Результат:
% ls -l
total 822368
-rw-r--r--@ 1 User group 104857600 Dec 20 22:56 part.aa
-rw-r--r--@ 1 User group 104857600 Dec 20 22:56 part.ab
-rw-r--r--@ 1 User group 808601 Dec 20 22:56 part.ab
-rwx------@ 1 User group 210523801 Feb 24 2023 video.mp4
В результате выполнения команды split файл video.mp4 разбит на три части: part.aa, part.ab и part.ab.
Создайте составную загрузку в бакете
Если у вас еще нет интерфейса командной строки Yandex Cloud (CLI), установите и инициализируйте его.
По умолчанию используется каталог, указанный при создании профиля CLI. Чтобы изменить каталог по умолчанию, используйте команду yc config set folder-id <идентификатор_каталога>. Также для любой команды вы можете указать другой каталог с помощью параметров --folder-name или --folder-id.
-
Посмотрите описание команды CLI для создания составной загрузки объекта в бакет:
yc storage s3api create-multipart-upload --help -
Получите список бакетов в каталоге по умолчанию:
yc storage bucket listРезультат:
+------------------+----------------------+-------------+-----------------------+---------------------+ | NAME | FOLDER ID | MAX SIZE | DEFAULT STORAGE CLASS | CREATED AT | +------------------+----------------------+-------------+-----------------------+---------------------+ | first-bucket | b1gmit33ngp6******** | 53687091200 | STANDARD | 2022-12-16 13:58:18 | +------------------+----------------------+-------------+-----------------------+---------------------+ -
Создайте составную загрузку:
yc storage s3api create-multipart-upload \ --bucket <имя_бакета> \ --key <ключ_объекта>Где:
--bucket— имя вашего бакета.--key— ключ объекта, по которому объект будет храниться в бакете.
Результат:
request_id: 644e7c89******** bucket: first-bucket key: video.mp4 upload_id: 000629B7********Сохраните значение идентификатора составной загрузки (
upload_id) — оно понадобится для выполнения следующих шагов.Подробнее о команде
yc storage s3api create-multipart-uploadчитайте в справочнике CLI.
Если у вас еще нет AWS CLI, установите и сконфигурируйте его.
-
Получите список доступных бакетов:
aws s3api list-buckets \ --endpoint-url=https://storage.yandexcloud.netРезультат:
{ "Buckets": [ { "Name": "new-bucket", "CreationDate": "2024-12-20T17:48:17+00:00" }, { "Name": "first-bucket", "CreationDate": "2023-12-28T12:20:49.538000+00:00" } ], "Owner": { "DisplayName": "", "ID": "" } } -
Создайте составную загрузку:
aws s3api create-multipart-upload \ --endpoint-url=https://storage.yandexcloud.net \ --bucket <имя_бакета> \ --key <ключ_объекта>Где:
--bucket— имя вашего бакета.--key— ключ объекта, по которому объект будет храниться в бакете.
Результат:
{ "Bucket": "first-bucket", "Key": "video.mp4", "UploadId": "000629C2********" }Сохраните значение идентификатора составной загрузки (
UploadId) — оно понадобится для выполнения следующих шагов.
Чтобы создать составную загрузку объекта в бакете, воспользуйтесь методом S3 API startUpload.
Загрузите в бакет составные части объекта
Загрузите первую часть объекта:
-
Посмотрите описание команды CLI для загрузки составной части объекта в бакет:
yc storage s3api upload-part --help -
Выполните команду:
yc storage s3api upload-part \ --bucket <имя_бакета> \ --key <ключ_объекта> \ --upload-id <идентификатор_составной_загрузки> \ --part-number <порядковый_номер_части> \ --body <путь_к_файлу_с_составной_частью>Где:
-
--bucket— имя вашего бакета. -
--key— ключ объекта, по которому объект будет храниться в бакете. -
--upload-id— значение идентификатора составной загрузки, полученное на предыдущем шаге. -
--part-number— порядковый номер составной части объекта, загружаемой в бакет.Порядковый номер однозначно идентифицирует часть и определяет ее порядок в общей последовательности. Номер — это целое число в промежутке от 1 до 10000 включительно.
Если загружаются несколько частей с одинаковым номером, Object Storage сохраняет последнюю поступившую.
Размер каждой части, кроме последней, должен быть не менее 5 МБ
-
--body— путь к файлу, в котором сохранена составная часть на компьютере пользователя.
Результат:
request_id: 7ab2820f******** etag: '"a2c44573954874e1a62a3f59********"'Сохраните значение
etag— оно понадобится для сборки объекта из частей на стороне бакета Object Storage.Подробнее о команде
yc storage s3api upload-partчитайте в справочнике CLI. -
aws s3api upload-part \
--endpoint-url=https://storage.yandexcloud.net \
--bucket <имя_бакета> \
--key <ключ_объекта> \
--upload-id <идентификатор_составной_загрузки> \
--part-number <порядковый_номер_части> \
--body <путь_к_файлу_с_составной_частью>
Где:
-
--bucket— имя вашего бакета. -
--key— ключ объекта, по которому объект будет храниться в бакете. -
--upload-id— значение идентификатора составной загрузки, полученное на предыдущем шаге. -
--part-number— порядковый номер составной части объекта, загружаемой в бакет.Порядковый номер однозначно идентифицирует часть и определяет ее порядок в общей последовательности. Номер — это целое число в промежутке от 1 до 10000 включительно.
Если загружаются несколько частей с одинаковым номером, Object Storage сохраняет последнюю поступившую.
Размер каждой части, кроме последней, должен быть не менее 5 МБ
-
--body— путь к файлу, в котором сохранена составная часть на компьютере пользователя.
Результат:
{
"ETag": "\"a2c44573954874e1a62a3f59********\""
}
Сохраните значение ETag — оно понадобится для сборки объекта из частей на стороне бакета Object Storage.
Чтобы загрузить в бакет составную часть объекта, воспользуйтесь методом S3 API uploadPart.
Аналогичным образом загрузите остальные составные части объекта, последовательно заменяя в командах порядковый номер --part-number и путь к файлу составной части --body. Не забывайте сохранять для каждой загруженной части полученное уникальное значение etag.
Завершите составную загрузку
После успешной загрузки всех составных частей, завершите составную загрузку и соберите загруженные в бакет части в целый объект:
-
Посмотрите описание команды CLI для завершения составной загрузки объекта в бакет:
yc storage s3api complete-multipart-upload --help -
Выполните команду:
yc storage s3api complete-multipart-upload \ --bucket <имя_бакета> \ --key <ключ_объекта> \ --upload-id <идентификатор_составной_загрузки> \ --multipart-upload \ '{"Parts": [{"PartNumber": <порядковый_номер_части_1>, "ETag": "<значение_etag_части_1>"}, {"PartNumber": <порядковый_номер_части_2>, "ETag": "<значение_etag_части_2>"}, ..., {"PartNumber": <порядковый_номер_части_n>, "ETag": "<значение_etag_части_n>"}]}'Где:
-
--bucket— имя вашего бакета. -
--key— ключ объекта, по которому объект будет храниться в бакете. -
--upload-id— значение идентификатора составной загрузки, полученное на предыдущем шаге. -
--multipart-upload— объект, содержащий порядковые номера и значенияetagвсех загруженных составных частей в нужном порядке. Например:--multipart-upload \ '{"Parts": [{"PartNumber": 1, "ETag": "a2c44573954874e1a62a3f59********"}, {"PartNumber": 2, "ETag": "3c0e70e1d05bd4e2500f5a90********"}, {"PartNumber": 3, "ETag": "953ecfff0150fd0970008320********"}]}'
Результат:
request_id: bde94875******** bucket: first-bucket key: video.mp4 etag: '"040d1fe80bd1d4f12728b192********-3"' location: https://storage.yandexcloud.net:443/first-bucket/video.mp4Подробнее о команде
yc storage s3api complete-multipart-uploadчитайте в справочнике CLI. -
aws s3api complete-multipart-upload \
--endpoint-url=https://storage.yandexcloud.net \
--bucket <имя_бакета> \
--key <ключ_объекта> \
--upload-id <идентификатор_составной_загрузки> \
--multipart-upload \
'{"Parts": [{"PartNumber": <порядковый_номер_части_1>, "ETag": "<значение_etag_части_1>"}, {"PartNumber": <порядковый_номер_части_2>, "ETag": "<значение_etag_части_2>"}, ..., {"PartNumber": <порядковый_номер_части_n>, "ETag": "<значение_etag_части_n>"}]}'
Где:
-
--bucket— имя вашего бакета. -
--key— ключ объекта, по которому объект будет храниться в бакете. -
--upload-id— значение идентификатора составной загрузки, полученное на предыдущем шаге. -
--multipart-upload— объект, содержащий порядковые номера и значенияetagвсех загруженных составных частей в нужном порядке. Например:--multipart-upload \ '{"Parts": [{"PartNumber": 1, "ETag": "a2c44573954874e1a62a3f59********"}, {"PartNumber": 2, "ETag": "3c0e70e1d05bd4e2500f5a90********"}, {"PartNumber": 3, "ETag": "953ecfff0150fd0970008320********"}]}'
Результат:
{
"Location": "https://storage.yandexcloud.net/first-bucket/video.mp4",
"Bucket": "first-bucket",
"Key": "video.mp4",
"ETag": "\"040d1fe80bd1d4f12728b192********-3\""
}
Чтобы завершить составную загрузку объекта, воспользуйтесь методом S3 API completeUpload.
Объект с заданным префиксом создан в бакете Object Storage из загруженных составных частей. Воспользуйтесь инструкцией, чтобы получить информацию о созданном объекте.
Завершите составную загрузку с условием (conditional writes)
Вы можете использовать условия при завершении составной загрузки, а также при обычной загрузке объекта.
Завершение составной загрузки с условием по ETag
-
Если у вас еще нет AWS CLI, установите и сконфигурируйте его.
-
Чтобы завершить составную загрузку только при существовании объекта с определенным
ETag, выполните команду:aws s3api complete-multipart-upload \ --endpoint-url=https://storage.yandexcloud.net \ --bucket <имя_бакета> \ --key <ключ_объекта> \ --upload-id <идентификатор_составной_загрузки> \ --multipart-upload \ '{"Parts": [{"PartNumber": <порядковый_номер_части_1>, "ETag": "<значение_etag_части_1>"}, {"PartNumber": <порядковый_номер_части_2>, "ETag": "<значение_etag_части_2>"}, ..., {"PartNumber": <порядковый_номер_части_n>, "ETag": "<значение_etag_части_n>"}]}' \ --if-match "<ETag_объекта>"Где:
-
--bucket— имя вашего бакета. -
--key— ключ объекта, по которому объект будет храниться в бакете. -
--upload-id— значение идентификатора составной загрузки, полученное на предыдущем шаге. -
--multipart-upload— объект, содержащий порядковые номера и значенияetagвсех загруженных составных частей в нужном порядке. Например:--multipart-upload \ '{"Parts": [{"PartNumber": 1, "ETag": "a2c44573954874e1a62a3f59********"}, {"PartNumber": 2, "ETag": "3c0e70e1d05bd4e2500f5a90********"}, {"PartNumber": 3, "ETag": "953ecfff0150fd0970008320********"}]}' -
--if-match— текущийETagобъекта, например\"d41d8cd98f00b204e9800998********\". Запись выполнится, только если по указанному ключу уже существует объект и его текущийETagсовпадает.
Результат:
{ "Location": "https://storage.yandexcloud.net/first-bucket/video.mp4", "Bucket": "first-bucket", "Key": "video.mp4", "ETag": "\"040d1fe80bd1d4f12728b192********-3\"" } -
Чтобы завершить составную загрузку только при существовании объекта с определенным ETag, воспользуйтесь методом S3 API completeUpload с заголовком --if-match.
Завершение составной загрузки с условием отсутствия
-
Если у вас еще нет AWS CLI, установите и сконфигурируйте его.
-
Чтобы завершить составную загрузку только при отсутствии в бакете объекта с определенным ключом, выполните команду:
aws s3api complete-multipart-upload \ --endpoint-url=https://storage.yandexcloud.net \ --bucket <имя_бакета> \ --key <ключ_объекта> \ --upload-id <идентификатор_составной_загрузки> \ --multipart-upload \ '{"Parts": [{"PartNumber": <порядковый_номер_части_1>, "ETag": "<значение_etag_части_1>"}, {"PartNumber": <порядковый_номер_части_2>, "ETag": "<значение_etag_части_2>"}, ..., {"PartNumber": <порядковый_номер_части_n>, "ETag": "<значение_etag_части_n>"}]}' \ --if-none-match "*"Где:
-
--bucket— имя вашего бакета. -
--key— ключ объекта, по которому объект будет храниться в бакете. -
--upload-id— значение идентификатора составной загрузки, полученное на предыдущем шаге. -
--multipart-upload— объект, содержащий порядковые номера и значенияetagвсех загруженных составных частей в нужном порядке. Например:--multipart-upload \ '{"Parts": [{"PartNumber": 1, "ETag": "a2c44573954874e1a62a3f59********"}, {"PartNumber": 2, "ETag": "3c0e70e1d05bd4e2500f5a90********"}, {"PartNumber": 3, "ETag": "953ecfff0150fd0970008320********"}]}' -
--if-none-match— укажите"*", чтобы запись выполнилась, только если по указанному ключу еще нет объекта.
Результат:
{ "Location": "https://storage.yandexcloud.net/first-bucket/video.mp4", "Bucket": "first-bucket", "Key": "video.mp4", "ETag": "\"040d1fe80bd1d4f12728b192********-3\"" } -
Чтобы завершить составную загрузку только при отсутствии в бакете объекта с определенным ключом, воспользуйтесь методом S3 API completeUpload с заголовком --if-none-match.