Effizienteste Methode zum Löschen von S3-Dateien im Batch


15

Ich möchte in der Lage sein, Tausende oder Zehntausende von Dateien gleichzeitig auf S3 zu löschen. Jede Datei würde zwischen 1 MB und 50 MB groß sein. Natürlich möchte ich nicht, dass der Benutzer (oder mein Server) wartet, während die Dateien gelöscht werden. Daher die Fragen:

  1. Wie geht S3 mit dem Löschen von Dateien um, insbesondere beim Löschen einer großen Anzahl von Dateien?
  2. Gibt es eine effiziente Möglichkeit, dies zu tun und AWS dazu zu bringen, den größten Teil der Arbeit zu erledigen? Mit effizient meine ich, dass S3 mit der geringsten Anzahl von Anforderungen und der geringsten Zeit mit der geringsten Anzahl von Ressourcen auf meinen Servern belastet wird.

Antworten:


11

AWS unterstützt das Massenlöschen von bis zu 1000 Objekten pro Anforderung mithilfe der S3-REST-API und ihrer verschiedenen Wrapper. Bei dieser Methode wird davon ausgegangen, dass Sie die zu entfernenden S3-Objektschlüssel kennen (dh, sie sind nicht für die Verarbeitung von Aufbewahrungsrichtlinien, Dateien mit einer bestimmten Größe usw. ausgelegt).

Die S3-REST-API kann angeben, dass bis zu 1000 Dateien in einer einzelnen Anforderung gelöscht werden sollen. Dies muss schneller sein als das Ausführen einzelner Anforderungen. Denken Sie daran, dass jede Anforderung eine HTTP-Anforderung (also eine TCP-Anforderung) ist. Daher ist jede Anforderung mit einem Mehraufwand verbunden. Sie müssen nur die Schlüssel der Objekte kennen und eine HTTP-Anfrage erstellen (oder einen Wrapper in der Sprache Ihrer Wahl verwenden). AWS bietet hervorragende Informationen zu dieser Funktion und ihrer Verwendung . Wählen Sie einfach die Methode, mit der Sie sich am wohlsten fühlen!

Ich gehe davon aus, dass in Ihrem Anwendungsfall Endbenutzer eine Reihe bestimmter Dateien angeben, die gleichzeitig gelöscht werden sollen. Anstatt eine Aufgabe wie "Alle Objekte löschen, die auf Bilddateien verweisen" oder "Alle Dateien löschen, die älter als ein bestimmtes Datum sind" zu starten (was meines Erachtens in S3 einfach zu konfigurieren ist).

In diesem Fall kennen Sie die Schlüssel, die Sie löschen müssen. Dies bedeutet auch, dass der Benutzer mehr Echtzeit-Feedback darüber erhalten möchte, ob seine Datei erfolgreich gelöscht wurde oder nicht. Die Verweise auf exakte Schlüssel sollten sehr schnell sein, da S3 so konzipiert wurde, dass es trotz der Verarbeitung einer extrem großen Datenmenge effizient skaliert.

Wenn nicht, können Sie asynchrone API-Aufrufe untersuchen. In diesem Blogbeitrag können Sie nachlesen, wie sie im Allgemeinen funktionieren würden, oder nach Anleitungen in der Sprache Ihrer Wahl suchen. Auf diese Weise kann die Löschanforderung einen eigenen Thread belegen, und der Rest des Codes kann ausgeführt werden, ohne dass ein Benutzer wartet. Sie können die Anforderung auch in eine Warteschlange verschieben. . . Beide Optionen erschweren jedoch unnötigerweise entweder Ihren Code (asynchroner Code kann ärgerlich sein) oder Ihre Umgebung (Sie benötigen einen Service / Daemon / Container / Server für die Verarbeitung der Warteschlange. Daher würde ich dieses Szenario nach Möglichkeit vermeiden.

Bearbeiten: Ich habe nicht den Ruf, mehr als 2 Links zu posten. Aber Sie hier Amazon Kommentare auf Anfrage Preis und Leistung sehen: http://docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html Und die s3 FAQ Kommentare , die Masse deleiton ist die weit, wenn möglich.


15

Die quälend langsame Option ist, s3 rm --recursivewenn Sie tatsächlich gerne warten.

Die parallele Ausführung s3 rm --recursivemit unterschiedlichen --includeMustern ist etwas schneller, es wird jedoch noch viel Zeit darauf gewartet, da jeder Prozess einzeln die gesamte Schlüsselliste abruft, um den --includeMusterabgleich lokal durchzuführen .

Bulk-Löschung eingeben.

Ich stellte fest, dass ich die höchste Geschwindigkeit erzielen konnte, indem ich 1000 Schlüssel gleichzeitig mit löschte aws s3api delete-objects.

Hier ist ein Beispiel:

cat file-of-keys | xargs -P8 -n1000 bash -c 'aws s3api delete-objects --bucket MY_BUCKET_NAME --delete "Objects=[$(printf "{Key=%s}," "$@")],Quiet=true"' _
  • Die -P8Option on xargssteuert die Parallelität. In diesem Fall ist es acht, was 8 Instanzen von jeweils 1000 Löschungen bedeutet.
  • Mit dieser -n1000Option werden xargs1000 Tasten für jeden aws s3api delete-objectsAnruf gebündelt .
  • Durch Entfernen ,Quiet=trueoder Ändern dieser falseOption werden Serverantworten ausgegeben.
  • Hinweis: Am _Ende dieser Befehlszeile wird ein leicht übersehen . @VladNikiforov hat einen hervorragenden Kommentar dazu gepostet, wofür es in dem Kommentar steht, also werde ich nur darauf verlinken.

Aber wie kommst du dahin file-of-keys?

Wenn Sie bereits eine Liste mit Schlüsseln haben, ist das gut für Sie. Auftrag erledigt.

Wenn nicht, hier ist eine Möglichkeit, denke ich:

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

8
Toller Ansatz, aber ich fand, dass die Auflistung der Schlüssel der Engpass war. Das geht viel schneller: aws s3api list-objects --output text --bucket BUCKET --query 'Contents[].[Key]' | pv -l > BUCKET.keys Und dann Objekte entfernen (das hat ausgereicht, dass durch das Überschreiten von 1 parallelen Prozess die Ratenbeschränkungen für das Löschen von Objekten erreicht wurden): 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
Du hättest am _Ende wahrscheinlich auch die Wichtigkeit betonen sollen :) Ich habe es verpasst und dann habe ich eine ganze Weile gebraucht, um zu verstehen, warum das erste Element übersprungen wird. Der Punkt ist, dass bash -calle Argumente als Positionsparameter übergeben werden, beginnend mit $0, während "$ @" nur Parameter verarbeitet, die mit beginnen $1. Der Unterstrich-Dummy wird also benötigt, um die Position von zu füllen $0.
Vlad Nikiforov

@VladNikiforov Cheers, bearbeitet.
Antak

3
Ein Problem, das ich bei diesem Ansatz (entweder von Antak oder Vlad) festgestellt habe, ist, dass er im Fehlerfall nicht einfach wiederaufgenommen werden kann. Wenn Sie viele Schlüssel löschen (in meinem Fall 10 Millionen), liegt möglicherweise ein Netzwerkfehler oder ein Drosselfehler vor, der dies verhindert. Um dies zu verbessern, habe ich split -l 1000meine Schlüsseldatei in 1000 Schlüsselstapel aufgeteilt. Jetzt kann ich für jede Datei den Löschbefehl ausgeben und dann die Datei löschen. Wenn etwas schief geht, kann ich weitermachen.
Joelittlejohn

Wenn Sie nur eine Liste der Schlüssel wünschen, würde ich denken, aws s3 ls "s3://MY_BUCKET_NAME/SOME_SUB_DIR" | awk '{print $4}'wäre einfacher und Sie können ein hinzufügen | grep, um das von dort nach unten zu filtern.
Hayden

3

Ich war frustriert über die Leistung der Webkonsole für diese Aufgabe. Ich fand, dass der AWS CLI- Befehl dies gut macht. Beispielsweise:

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

Bei einer großen Dateihierarchie kann dies einige Zeit in Anspruch nehmen. Sie können dies in einer tmuxoder einer screenSitzung ausführen und später erneut versuchen.


2
Es sieht so aus, als würde der aws s3 rm --recursiveBefehl Dateien einzeln löschen. Obwohl es schneller als die Webkonsole ist, könnte es beim Löschen vieler Dateien viel schneller sein, wenn es in großen Mengen gelöscht wird
Brandon


0

Ohne zu wissen, wie Sie die S3-Buckets verwalten, kann dies besonders nützlich sein oder auch nicht.

Das AWS CLI-Tool verfügt über eine Option namens "Sync", die besonders effektiv sein kann, um sicherzustellen, dass s3 die richtigen Objekte hat. Wenn Sie oder Ihre Benutzer S3 von einem lokalen Dateisystem aus verwalten, können Sie möglicherweise eine Menge Arbeit sparen, um mithilfe der CLI-Tools zu bestimmen, welche Objekte gelöscht werden müssen.

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


0

Es wurde bereits der s3 syncBefehl erwähnt, jedoch ohne Beispiel und das Wort zur --deleteOption.

Ich habe den schnellsten Weg gefunden, den Inhalt eines Ordners im S3Eimer zu löschen my_bucket:

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.