Назад | Перейти на главную страницу

Самый эффективный способ пакетного удаления файлов S3

Я хотел бы иметь возможность пакетного удаления тысяч или десятков тысяч файлов за раз на S3. Каждый файл может иметь размер от 1 МБ до 50 МБ. Естественно, я не хочу, чтобы пользователь (или мой сервер) ждал, пока файлы находятся в процессе удаления. Отсюда вопросы:

  1. Как S3 обрабатывает удаление файлов, особенно при удалении большого количества файлов?
  2. Есть ли эффективный способ сделать это и заставить AWS выполнять большую часть работы? Под эффективностью я подразумеваю выполнение наименьшего количества запросов к S3 и занятие наименьшим количеством времени, используя наименьшее количество ресурсов на моих серверах.

В мучительно медленно вариант s3 rm --recursive если тебе действительно нравится ждать.

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

Введите массовое удаление.

Я обнаружил, что смог добиться максимальной скорости, удаляя по 1000 ключей за раз, используя aws s3api delete-objects.

Вот пример:

cat file-of-keys | xargs -P8 -n1000 bash -c 'aws s3api delete-objects --bucket MY_BUCKET_NAME --delete "Objects=[$(printf "{Key=%s}," "$@")],Quiet=true"' _
  • В -P8 вариант на xargs контролирует параллелизм. В данном случае их восемь, что означает 8 экземпляров по 1000 удалений за раз.
  • В -n1000 опция говорит xargs связать 1000 ключей для каждого aws s3api delete-objects вызов.
  • Удаление ,Quiet=true или изменив его на false будет извергать ответы сервера.
  • Примечание: легко пропустить _ в конце этой командной строки. @VladNikiforov написал отличный комментарий для чего это в комментарии так что я собираюсь просто дать ссылку на это.

Но как получить file-of-keys?

Если у вас уже есть список ключей, хорошо. Работа завершена.

Если нет, я думаю, вот один из способов:

aws s3 ls "s3://MY_BUCKET_NAME/SOME_SUB_DIR" | sed -nre "s|[0-9-]+ [0-9:]+ +[0-9]+ |SOME_SUB_DIR|p" >file-of-keys

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

S3 REST API может указать до 1000 файлов, которые необходимо удалить в одном запросе, что должно быть быстрее, чем выполнение отдельных запросов. Помните, что каждый запрос является запросом HTTP (то есть TCP). Таким образом, каждый запрос несет накладные расходы. Вам просто нужно знать ключи объектов и создать HTTP-запрос (или использовать оболочку на выбранном вами языке). AWS предоставляет отличную информацию об этой функции и ее использовании.. Просто выберите наиболее удобный для вас метод!

Я предполагаю, что ваш вариант использования предполагает, что конечные пользователи указывают несколько конкретных файлов для одновременного удаления. Вместо того, чтобы инициировать такую ​​задачу, как «очистить все объекты, относящиеся к файлам изображений» или «очистить все файлы старше определенной даты» (которые, как я считаю, легко настроить отдельно в S3).

Если да, то вы знаете ключи, которые нужно удалить. Это также означает, что пользователю понравится больше отзывов в реальном времени о том, был ли его файл удален успешно или нет. Ссылки на точные ключи должны быть очень быстрыми, поскольку S3 был разработан для эффективного масштабирования, несмотря на обработку чрезвычайно большого количества данных.

Если нет, вы можете изучить асинхронные вызовы API. Вы можете немного узнать о том, как они будут работать в целом, из этого Сообщение блога или поищите, как это сделать, на выбранном вами языке. Это позволит запросу на удаление занять свой собственный поток, а остальная часть кода может выполняться, не заставляя пользователя ждать. Или вы можете выгрузить запрос в очередь. . . Но оба эти варианта без необходимости усложняют либо ваш код (асинхронный код может раздражать), либо вашу среду (вам понадобится служба / демон / контейнер / сервер для обработки очереди. Поэтому я бы по возможности избегал этого сценария.

Изменить: у меня нет репутации, чтобы размещать более двух ссылок. Но вы можете увидеть комментарии Amazon по скорости запросов и производительности здесь: http://docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html И в s3 faq говорится, что массовое удаление - это лучший способ, если это возможно.

Меня разочаровала производительность веб-консоли для этой задачи. Я обнаружил, что AWS CLI команда делает это хорошо. Например:

aws s3 rm --recursive s3://my-bucket-name/huge-directory-full-of-files

Для большой файловой иерархии это может занять значительное время. Вы можете установить это в tmux или screen сеанс и проверьте позже.

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

https://docs.aws.amazon.com/AmazonS3/latest/user-guide/create-lifecycle.html

Там уже упоминалось о s3 sync команда раньше, но без примера и слов о --delete вариант.

Я нашел самый быстрый способ удалить содержимое папки в S3 ведро my_bucket по:

aws s3 sync --delete "local-empty-dir/" "s3://my_bucket/path-to-clear"

Не зная, как вы управляете ведрами s3, это может быть, а может и не быть особенно полезным.

В инструментах AWS CLI есть опция «синхронизация», которая может быть особенно эффективной для обеспечения того, чтобы s3 имел правильные объекты. Если вы или ваши пользователи управляете S3 из локальной файловой системы, вы можете сэкономить массу работы, определяя, какие объекты необходимо удалить, с помощью инструментов CLI.

http://docs.aws.amazon.com/cli/latest/reference/s3/sync.html