- PVSM.RU - https://www.pvsm.ru -

Объектные хранилища с доступом на базе S3 API — это, возможно, лучшее решение для хранения больших объемов данных. Однако при загрузке крупных файлов могут возникнуть проблемы. Например, долгая передача данных из-за сетевых ограничений или таймауты и обрывы соединения. Как ни крути, а интернет даже здесь диктует свои условия. Попробуем их обойти с помощью мультипарт-загрузки.
Привет! Меня зовут Гришин Александр, я продакт-менеджер в Selectel и отвечаю за развитие объектного хранилища и облачных баз данных. В этой статье я расскажу, как загружать большие файлы в S3 с помощью мультипарт-загрузки, используя Python и boto3. Под катом вы узнаете, как работает этот механизм и как его настроить для эффективной работы.
Скоро выпустим новый комикс о путешествиях ИБ-специалиста! Регистрируйтесь [1], чтобы узнать о публикации первыми. Бонусом сможете выиграть один из 15 комплектов призов.
Используйте навигацию, если не хотите читать текст полностью:
→ Как работает мультипарт-загрузка в S3 [2]
→ Пример на Python [3]
→ Оптимизация и рекомендации [4]
→ А нужен ли код [5]
Мультипарт-загрузка состоит из нескольких этапов.
1. Инициализация загрузки [6] — создание уникального идентификатора загрузки.
response = s3_client.create_multipart_upload(Bucket=BUCKET_NAME, Key=KEY)
upload_id = response["UploadId"]
Этот запрос создает мультипарт-загрузку и возвращает UploadId, который используется для загрузки частей файла.
2. Разделение файла на части и их параллельная отправка [7].
response = s3_client.upload_part(
Bucket=BUCKET_NAME,
Key=KEY,
PartNumber=part_number,
UploadId=upload_id,
Body=data
)
3. Завершение загрузки [8] и сборка частей в единый объект:
s3_client.complete_multipart_upload(
Bucket=BUCKET_NAME,
Key=KEY,
UploadId=upload_id,
MultipartUpload={"Parts": parts}
)
4. При необходимости — отмена загрузки (например, если загрузка не удалась).

Схема разбиения объекта на парты и их параллельная загрузка в S3.

Реализацию мультипарт-загрузки я разделю на два этапа: работа в панели управления и работа на клиенте. Итак.
В целом, здесь нам нужно просто создать и настроить контейнер объектного хранилища. Очень подробный пошаговый гайд вы найдете в недавней статье [9] моего коллеги. Я же перечислю только основные шаги:

Работа с сервисными пользователями в панели управления.
Прежде всего, установите библиотеку boto3. Это делается командой в терминале:
pip install boto3
Теперь подключаем библиотеки и пишем код для загрузки файла в объектное хранилище, используя мультипарт-загрузку:
import boto3
import os
# Настройки подключения к Selectel S3
S3_ENDPOINT = "https://s3.ru-1.storage.selcloud.ru" # Укажите ваш региональный endpoint
ACCESS_KEY = "ТУТ_ВАШ_ACCESS_KEY"
SECRET_KEY = "ТУТ_ВАШ_SECRET_KEY"
BUCKET_NAME = "4habr"
FILE_PATH = "/Users/alex/Downloads/1.mp4" # Файл для загрузки
KEY = "thebigboy2.mp4" # Название объекта в S3
# Создаем S3 клиент
s3_client = boto3.client(
"s3",
endpoint_url=S3_ENDPOINT,
aws_access_key_id=ACCESS_KEY,
aws_secret_access_key=SECRET_KEY
)
# 1. Инициализация мультипартийной загрузки
response = s3_client.create_multipart_upload(Bucket=BUCKET_NAME, Key=KEY)
upload_id = response["UploadId"]
print(f"Multipart Upload ID: {upload_id}")
# 2. Разбиение файла на части и загрузка
PART_SIZE = 1 * 1024 * 1024 # Размер одной части (1MB)
parts = []
file_size = os.path.getsize(FILE_PATH)
try:
with open(FILE_PATH, "rb") as f:
part_number = 1
while True:
data = f.read(PART_SIZE)
if not data:
break
# Загружаем часть файла
response = s3_client.upload_part(
Bucket=BUCKET_NAME,
Key=KEY,
PartNumber=part_number,
UploadId=upload_id,
Body=data
)
# Добавляем информацию о части
parts.append({"PartNumber": part_number, "ETag": response["ETag"]})
print(f"Uploaded part {part_number}")
part_number += 1
# 3. Завершаем загрузку
s3_client.complete_multipart_upload(
Bucket=BUCKET_NAME,
Key=KEY,
UploadId=upload_id,
MultipartUpload={"Parts": parts}
)
print("Multipart upload completed!")
except Exception as e:
print("Upload failed:", str(e))
s3_client.abort_multipart_upload(Bucket=BUCKET_NAME, Key=KEY, UploadId=upload_id)
Как работает этот код:
Объект загружен [11]. Можно делиться им с друзьями. Чтобы увидеть результат работы со стороны хранилища, снова зайдите в панель управления. Перейдите в нужный проект в объектном хранилище и включите отображение служебных контейнеров в настройках (это необходимо, чтобы увидеть парты загруженного объекта). В основном контейнере вы увидите ссылку на загруженный объект, а в служебном — парты этого объекта. На скриншоте ниже это шесть объектов размером до 1 МБ.

Листинг мультипартов в интерфейсе хранилища.
Для примера выше я установил размер парта 1 МБ, но это было сделано умышленно с целью демонстрации. Не стоит это повторять. В реальных проектах для загрузки больших файлов лучше использовать значения существенно больше, хотя бы 50-100 МБ.
Для обработки ошибок добавьте повторную попытку загрузки парта в случае сетевых проблем. А также настройте удаление ненужных частей в случае таких ошибок. В Selectel мы всегда храним все составные части загрузки, поскольку не знаем, в какой момент со стороны клиента может прийти CompleteMultipartUpload [8] и нужны ли еще клиенту эти части.
В этой статья я использовал код только для демонстрации работы мультипартовой загрузки в объектное хранилище Selectel [12]. Для большего удобства рекомендую использовать готовые приложения, поддерживающие такую функциональность из коробки. К ним относятся:
Пользуясь случаем, выделю именно rclone т. к. недавно мы стали официальными технологическими партнерами [18] и получили нативную поддержку нашей услуги в этом клиенте.
Если у вас остались вопросы, смело задавайте их в комментариях, все обсудим. И поделитесь своим опытом, как вы ускоряете загрузку ваших приложений в объектное хранилище.
Автор: GrishinAlex
Источник [19]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/412773
Ссылки в тексте:
[1] Регистрируйтесь: https://promo.selectel.ru/multihacker/?utm_source=habr.com&utm_medium=referral&utm_campaign=comics_article_multiparts3_040325_banner_072_02_ord
[2] Как работает мультипарт-загрузка в S3: #1
[3] Пример на Python: #2
[4] Оптимизация и рекомендации: #3
[5] А нужен ли код: #4
[6] Инициализация загрузки: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html
[7] отправка: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html
[8] Завершение загрузки: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html
[9] в недавней статье: https://habr.com/ru/companies/selectel/articles/875956/%232
[10] в панель управления: https://my.selectel.ru/?utm_source=habr.com&utm_medium=referral&utm_campaign=myselectel_article_multiparts3_040325_banner
[11] Объект загружен: https://b61d9a0c-54d1-47a6-971e-9b24c5dea7b4.selstorage.ru/thebigboy.mp4
[12] объектное хранилище Selectel: https://selectel.ru/services/cloud/storage/?utm_source=habr.com&utm_medium=referral&utm_campaign=storage_article_multiparts3_040325_content
[13] aws cli: https://docs.selectel.ru/cloud/object-storage/tools/aws-cli/
[14] rclone: https://docs.selectel.ru/cloud/object-storage/tools/rclone/
[15] s3cmd: https://docs.selectel.ru/cloud/object-storage/tools/s3cmd/
[16] cyberduck: https://docs.selectel.ru/cloud/object-storage/tools/cyberduck/
[17] s3fs: https://docs.selectel.ru/cloud/object-storage/tools/s3fs/
[18] мы стали официальными технологическими партнерами: https://rclone.org/s3/#selectel
[19] Источник: https://habr.com/ru/companies/selectel/articles/887698/?utm_source=habrahabr&utm_medium=rss&utm_campaign=887698
Нажмите здесь для печати.