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