Найбільш ефективний спосіб пакетного видалення файлів S3


16

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

  1. Як S3 обробляє видалення файлів, особливо при видаленні великої кількості файлів?
  2. Чи є ефективний спосіб зробити це і змусити AWS робити більшу частину роботи? Під ефективністю я маю на увазі піднесення найменшої кількості запитів до S3 і зайняття найменшої кількості часу, використовуючи найменшу кількість ресурсів на своїх серверах.

Відповіді:


12

AWS підтримує масове видалення до 1000 об'єктів на запит, використовуючи API SEST REST та його різні обгортки. Цей метод передбачає, що ви знаєте об'єктні ключі S3, які ви хочете видалити (тобто він не розроблений для обробки чогось типу політики збереження, файлів із певним розміром тощо).

API SEST REST може вказати до 1000 файлів, які потрібно видалити в одному запиті, що потрібно швидше, ніж робити окремі запити. Пам'ятайте, кожен запит - це запит HTTP (таким чином, TCP). Тому кожен запит несе накладні витрати. Вам просто потрібно знати ключі об’єктів і створити HTTP-запит (або використовувати обгортку на обраній вами мові). AWS надає чудову інформацію про цю функцію та її використання . Просто виберіть метод, який вам найбільше подобається!

Я припускаю, що у вашому випадку використання кінцеві користувачі вказують відразу кілька конкретних файлів, які потрібно видалити. Замість того, щоб ініціювати таке завдання, як "очистити всі об'єкти, які посилаються на файли зображень" або "очистити всі файли, старші за певну дату" (які, на мою думку, легко налаштувати окремо в S3).

Якщо так, ви знаєте ключі, які потрібно видалити. Це також означає, що користувачеві сподобається більше відгуків у реальному часі про те, успішно видалено їх файл чи ні. Посилання на точні ключі повинні бути дуже швидкими, оскільки S3 був розроблений для ефективного масштабування, незважаючи на обробку надзвичайно великої кількості даних.

Якщо ні, ви можете переглянути асинхронні виклики API. Ви можете прочитати трохи про те, як вони взагалі працюють, із цієї публікації в блозі або шукати, як це зробити на обраній вами мові. Це дозволило б запиту на видалення займати власний потік, а решту коду можна виконати, не змушуючи користувача чекати. Або ви можете завантажити запит до черги. . . Але обидва ці варіанти непотрібно ускладнювати або ваш код (асинхронний код може дратувати), або ваше оточення (для обробки черги вам потрібна служба / демон / контейнер / сервер. Тому я уникаю цього сценарію, якщо це можливо.

Редагувати: Я не маю репутації публікувати більше 2 посилань. Але ви можете побачити коментарі Amazon щодо швидкості запиту та продуктивності тут: http://docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html І коментарі s3 faq, які масово видаляють, є шлях, якщо це можливо.


19

Болісно повільний варіант , 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

10
Чудовий підхід, але я виявив, що перелік ключів було вузьким місцем. Це набагато швидше: aws s3api list-objects --output text --bucket BUCKET --query 'Contents[].[Key]' | pv -l > BUCKET.keys а потім видалення об'єктів (цього було достатньо, щоб перехід 1 паралельного процесу досягнув обмежень швидкості для видалення об'єкта): tail -n+0 BUCKET.keys | pv -l | grep -v -e "'" | tr '\n' '\0' | xargs -0 -P1 -n1000 bash -c 'aws s3api delete-objects --bucket BUCKET --delete "Objects=[$(printf "{Key=%q}," "$@")],Quiet=true"' _
SEK

2
Напевно, ви також мали б підкреслити важливість, _зрештою :) Я пропустив це, і тоді мені знадобилося досить багато часу, щоб зрозуміти, чому перший елемент пропускається. Справа в тому, що bash -cвсі аргументи передаються як позиційні параметри, починаючи з $0, тоді як "$ @" обробляє лише параметри, починаючи з $1. Тож підкреслена манекен потрібна для заповнення позиції $0.
Влад Никифоров

@VladNikiforov Ура, відредаговано.
антак

3
Одна з проблем, які я знайшов при такому підході (або від Антака, або від Влада), полягає в тому, що це не легко відновити, якщо є помилка. Якщо ви видаляєте багато клавіш (в моєму випадку 10 М), можливо, з’явилася помилка в мережі або помилка дроселювання, що порушує цю проблему. Щоб покращити це, я використовував split -l 1000для розбиття файлів ключів на 1000 пакетів ключів. Тепер для кожного файлу я можу видати команду delete, а потім видалити файл. Якщо щось піде не так, я можу продовжувати.
joelittlejohn

Якщо ви просто хочете al список списку ключів, я думаю, що aws s3 ls "s3://MY_BUCKET_NAME/SOME_SUB_DIR" | awk '{print $4}'це буде простіше, і ви можете додати файл, | grepщоб фільтрувати його внизу.
Хайден

3

Мене розчарувало виконання веб-консолі для цього завдання. Я виявив, що команда AWS CLI робить це добре. Наприклад:

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

Для великої ієрархії файлів це може зайняти значну кількість часу. Ви можете встановити цей запуск у сеансі tmuxчи screenсеансі та перевірити його пізніше.


2
Схоже, aws s3 rm --recursiveкоманда видаляє файли окремо. Хоча швидше, ніж веб-консоль, при видаленні безлічі файлів це може бути набагато швидше, якби її видалили масово
Брендон,

2

Акуратний фокус - це використання правил життєвого циклу для обробки видалення. Ви можете встановити чергу для видалення потрібного префікса або об'єктів, а Amazon просто подбає про видалення.

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


Будьте обережні, так як це може бути дуже дорогим , якщо у вас є багато об'єктів, stackoverflow.com/questions/54255990 / ...
Will

0

Не знаючи, як ви керуєте відрами s3, це може бути або не бути особливо корисним.

Інструменти AWS CLI мають опцію під назвою "синхронізація", яка може бути особливо ефективною для забезпечення правильних об'єктів s3. Якщо ви або ваші користувачі керуєте S3 з локальної файлової системи, можливо, ви зможете зберегти тону роботи, визначаючи, які об’єкти потрібно видалити за допомогою інструментів CLI.

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


0

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

Я знайшов найшвидший спосіб видалити вміст папки у S3відрі my_bucket:

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.