Как стать автором
Обновить

Асинхронно копируем объекты между регионами S3 с помощью Python

Уровень сложностиСредний
Время на прочтение6 мин
Количество просмотров4K
Всего голосов 28: ↑27 и ↓1+32
Комментарии10

Комментарии 10

Вопрос, зачем изобретать велосипед, если есть AWS DataSync?

Спасибо большое за ваш интерес и комментарий! AWS DataSync — действительно мощный и удобный инструмент для автоматизации репликации и перемещения данных. Однако в нашем случае:

- Мы рассматривали кейс с использованием инфраструктуры в России, а не AWS S3. У большинства компаний сейчас есть проблемы с использованием зарубежных сервисов. 

- В статье старался показать “принцип реализации репликации”, но вы правы лучше использовать готовое ПО. В итогах явно указал что не обязательно придумывать свои велосипеды, можно использовать готовое ПО. Спасибо вам!

- кост-эффективность. Использование AWS DataSync увеличит расходы для клиента. При реализации по подобной схеме весь трафик на репликацию будет бесплатный.

Первое - на бакете с большим числом файлом такой процесс копирования будет работать очень долго, т.к не распараллелен. Я писал подобный скрипт для s3 облака Яндекса и там 14 лямов файлов(около двух тб) почти неделю копировались,т.к работа была только на одном ядре. Не знаю, какого размера дампы у вас, но после определённого объема у вас процесс копирования может занимать больше часа времени.

Второе - что будет, если у вас в процессе копирования соединение упадёт? Исключение я вижу, но получается процесс попросту заново начнется? Стоит тогда хотя бы делать это по кускам или обрабатывать отвал так, чтобы последнее скопированное запоминалось и дальнейший процесс потом шёл с этого файла. Аналогичный вопрос в сторону тех файлов, которые уже были в бакете назначения - не стоит ли сначала сопоставить файлы и копировать только новые + изменившиеся? Понимаю,что это упомянуто в статье и что без индексации трафика этот вопрос некритичный, но на скорости это скажется ощутимо. В крайнем случае можно хотя бы в put_object() вписать ключ IfNoneMatch, чтобы файлы с одинаковым именем пропускались, если у вас гарантируется неизменность объектов после их загрузки в изначальный бакет.

Ну и присоединюсь к вопросу выше - у большинства отечественный s3 сохранена совместимость с AWS CLI, где есть команда Datasync( которая, к слову, распараллелена и можно даже прописать используемое в процессе количество ядер), в Selectel она отсутствует?

Спасибо большое за ваш вопрос и интерес. 

1. Не смотря на то, что мы уверены, что делаем самое производительное публичное S3-хранилище, процесс можно и нужно параллелить. Об одном из возможных вариантов рассказал в предыдущей статье https://habr.com/ru/companies/selectel/articles/887698/

2. Да, вы правы. Можно дозагружать при мультипарт-загрузке, и да, вы правы, что нужно учитывать текущее состояние листинга объектов на момент записи (об этом я пишу в Итогах этой статьи). Кстати, в следующей статье расскажу, как можно в подобном кейсе работать с версионированием. Это действительно крутая фича в S3. 

3. Прошу прощения, поспешил. Как и писал в предыдущих статьях, мы поддерживаем интеграции с ПО, которое использует S3 API. И вы правы: можно использовать любой клиент для этой работы. Код представлен лишь для раскрытия механики работы этих клиентов.

Еще раз спасибо что потратили свое время, прочитали статью и оставили фидбэк! Теперь мне будет легче смотивировать себя на следующую статью.

Помнится на большом количестве файлов я так и не смог получить список файлов из-за нехватки памяти.

Со стороны нашей услуги мы гарантируем что ресурсов хватит и представляем в договоре SLA по досутпности S3 API 99,98%. Возможно в вашем кейсе есть проблема с производительностью со стороны клиентского приложения.

Простите за мой скромный комментарий, а не проще было поднять minio client и с его помощью выполнить mc mirror src dst ?

Да, вы абсолютно правы. Разумеется, для фактической имплементации я бы рекомендовал использовать готовые клиенты, умеющие в S3 API: minio, aws cli, rclone и др. по. Как я указывал в заключении к статье, код и кейс представлены только для раскрытия принципиального подхода в реализации асинхронной репликации. Ведь любое приложение использует тот же S3 API что и python+boto3.

Вообще в boto3 put_object умеет принимать на вход стрим, поэтому в текущей реализации без дополнительного кода по обработке частично упавшей загрузки можно сразу соединить вход и выход без явного использования метода read(put_object сам его вызовет под капотом). Заодно неплохо сэкономить на локальном хранилище/памяти.

Вы абсолютно правы, так будет куда оптимальнее. Спасибо за дальный совет!

Зарегистрируйтесь на Хабре, чтобы оставить комментарий