Le moyen le plus efficace de supprimer par lots des fichiers S3


16

J'aimerais pouvoir supprimer par lots des milliers ou des dizaines de milliers de fichiers à la fois sur S3. Chaque fichier serait compris entre 1 Mo et 50 Mo. Naturellement, je ne veux pas que l'utilisateur (ou mon serveur) attende pendant que les fichiers sont en train d'être supprimés. D'où les questions:

  1. Comment S3 gère-t-il la suppression de fichiers, en particulier lors de la suppression d'un grand nombre de fichiers?
  2. Existe-t-il un moyen efficace de le faire et de faire en sorte qu'AWS effectue la majeure partie du travail? Par efficace, je veux dire en faisant le moins de demandes à S3 et en prenant le moins de temps en utilisant le moins de ressources sur mes serveurs.

Réponses:


12

AWS prend en charge la suppression en masse d'un maximum de 1 000 objets par demande à l'aide de l'API S3 REST et de ses divers wrappers. Cette méthode suppose que vous connaissez les clés d'objet S3 que vous souhaitez supprimer (c'est-à-dire qu'elles ne sont pas conçues pour gérer quelque chose comme une politique de rétention, des fichiers dépassant une certaine taille, etc.).

L'API S3 REST peut spécifier jusqu'à 1 000 fichiers à supprimer en une seule demande, ce qui doit être plus rapide que d'effectuer des demandes individuelles. N'oubliez pas que chaque requête est une requête HTTP (donc TCP). Ainsi, chaque demande entraîne des frais généraux. Il vous suffit de connaître les clés des objets et de créer une requête HTTP (ou d'utiliser un wrapper dans la langue de votre choix). AWS fournit d'excellentes informations sur cette fonctionnalité et son utilisation . Choisissez simplement la méthode qui vous convient le mieux!

Je suppose que votre cas d'utilisation implique que les utilisateurs finaux spécifient un certain nombre de fichiers spécifiques à supprimer en même temps. Plutôt que de lancer une tâche telle que "purger tous les objets qui font référence à des fichiers image" ou "purger tous les fichiers antérieurs à une certaine date" (ce qui, à mon avis, est facile à configurer séparément dans S3).

Si c'est le cas, vous saurez les clés que vous devez supprimer. Cela signifie également que l'utilisateur aimera plus de commentaires en temps réel sur la suppression ou non de son fichier. Les références aux clés exactes sont censées être très rapides, car S3 a été conçu pour évoluer efficacement malgré la gestion d'une très grande quantité de données.

Sinon, vous pouvez examiner les appels d'API asynchrones. Vous pouvez en savoir un peu plus sur leur fonctionnement en général dans cet article de blog ou rechercher comment le faire dans la langue de votre choix. Cela permettrait à la demande de suppression de prendre son propre thread, et le reste du code peut s'exécuter sans faire attendre un utilisateur. Ou, vous pouvez décharger la demande dans une file d'attente. . . Mais ces deux options compliquent inutilement votre code (le code asynchrone peut être ennuyeux) ou votre environnement (vous auriez besoin d'un service / démon / conteneur / serveur pour gérer la file d'attente. J'éviterais donc ce scénario si possible.

Edit: je n'ai pas la réputation de poster plus de 2 liens. Mais vous pouvez voir les commentaires d'Amazon sur le taux de demande et les performances ici: http://docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html Et la FAQ s3 commente que la suppression en bloc est le chemin à parcourir si possible.


17

L' option incroyablement lente est s3 rm --recursivesi vous aimez vraiment attendre.

L'exécution en parallèle s3 rm --recursiveavec des --includemodèles différents est légèrement plus rapide, mais beaucoup de temps est toujours passé à attendre, car chaque processus récupère individuellement la liste de clés entière afin d'effectuer localement la --includecorrespondance de modèle.

Entrez la suppression en bloc.

J'ai trouvé que je pouvais obtenir le plus de vitesse en supprimant 1000 touches à la fois en utilisant aws s3api delete-objects.

Voici un exemple:

cat file-of-keys | xargs -P8 -n1000 bash -c 'aws s3api delete-objects --bucket MY_BUCKET_NAME --delete "Objects=[$(printf "{Key=%s}," "$@")],Quiet=true"' _
  • L' -P8option on xargscontrôle le parallélisme. C'est huit dans ce cas, ce qui signifie 8 instances de 1000 suppressions à la fois.
  • L' -n1000option indique xargsde regrouper 1000 clés pour chaque aws s3api delete-objectsappel.
  • Le supprimer ,Quiet=trueou falsele remplacer par crachera les réponses du serveur.
  • Remarque: il y a facilement un manquant _à la fin de cette ligne de commande. @VladNikiforov a posté un excellent commentaire de ce à quoi il sert dans le commentaire, donc je vais simplement créer un lien vers cela.

Mais comment obtenez-vous file-of-keys?

Si vous avez déjà votre liste de clés, tant mieux pour vous. Travail terminé.

Sinon, voici une façon, je suppose:

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

9
Excellente approche, mais j'ai trouvé que répertorier les clés était le goulot d'étranglement. C'est beaucoup plus rapide: aws s3api list-objects --output text --bucket BUCKET --query 'Contents[].[Key]' | pv -l > BUCKET.keys Et puis supprimer des objets (cela suffisait pour que le fait de passer par 1 processus parallèle atteigne les limites de taux de suppression d'objets): 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
Vous auriez probablement dû également insister sur l'importance _à la fin :) Je l'ai manqué, puis il m'a fallu un certain temps pour comprendre pourquoi le premier élément était ignoré. Le fait est que bash -ctous les arguments passent en tant que paramètres positionnels, en commençant par $0, tandis que «$ @» traite uniquement les paramètres commençant par $1. Le mannequin de soulignement est donc nécessaire pour occuper le poste de $0.
Vlad Nikiforov

@VladNikiforov Cheers, édité.
antak

3
Un problème que j'ai trouvé avec cette approche (que ce soit d'Antak ou de Vlad) est qu'elle n'est pas facilement reproductible en cas d'erreur. Si vous supprimez un lot de clés (10M dans mon cas), vous pouvez avoir une erreur réseau ou une limitation, qui rompt cela. Donc, pour améliorer cela, j'ai l'habitude split -l 1000de diviser mon fichier de clés en 1000 lots de clés. Maintenant, pour chaque fichier, je peux lancer la commande de suppression, puis supprimer le fichier. Si quelque chose se passe mal, je peux continuer.
joelittlejohn

Si vous voulez juste une liste des clés, je pense que ce aws s3 ls "s3://MY_BUCKET_NAME/SOME_SUB_DIR" | awk '{print $4}'serait plus simple et vous pouvez ajouter un | greppour filtrer cela à partir de là.
Hayden

3

J'ai été frustré par les performances de la console Web pour cette tâche. J'ai trouvé que la commande AWS CLI le faisait bien. Par exemple:

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

Pour une hiérarchie de fichiers volumineux, cela peut prendre un certain temps. Vous pouvez définir cette exécution dans une tmuxou screensession et revenez plus tard.


2
Il semble que la aws s3 rm --recursivecommande supprime les fichiers individuellement. Bien que plus rapide que la console Web, lors de la suppression de nombreux fichiers, elle pourrait être beaucoup plus rapide si elle était supprimée en masse
Brandon


0

Sans savoir comment vous gérez les compartiments s3, cela peut ou peut ne pas être particulièrement utile.

Les outils AWS CLI ont une option appelée "sync" qui peut être particulièrement efficace pour garantir que s3 a les bons objets. Si vous, ou vos utilisateurs, gérez S3 à partir d'un système de fichiers local, vous pourrez peut-être économiser une tonne de travail en déterminant les objets à supprimer à l'aide des outils CLI.

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


0

Il est déjà fait mention de la s3 synccommande avant, mais sans exemple ni mot sur l' --deleteoption.

J'ai trouvé le moyen le plus rapide de supprimer le contenu du dossier dans le S3compartiment my_bucketen:

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.