Najbardziej wydajny sposób grupowego usuwania plików S3

16

Chciałbym móc grupowo usuwać tysiące lub dziesiątki tysięcy plików jednocześnie na S3. Każdy plik może mieć od 1 MB do 50 MB. Oczywiście nie chcę, aby użytkownik (lub mój serwer) czekał na usunięcie plików. Stąd pytania:

  1. Jak S3 radzi sobie z usuwaniem plików, zwłaszcza przy usuwaniu dużej liczby plików?
  2. Czy istnieje skuteczny sposób na zrobienie tego i sprawienie, aby AWS wykonał większość pracy? Pod pojęciem wydajności mam na myśli wysyłanie najmniejszej liczby żądań do S3 i poświęcanie jak najmniej czasu przy użyciu najmniejszej ilości zasobów na moich serwerach.
SudoKill
źródło

Odpowiedzi:

12

AWS obsługuje usuwanie zbiorcze do 1000 obiektów na żądanie przy użyciu interfejsu API REST S3 i jego różnych opakowań. Ta metoda zakłada, że ​​znasz klucze obiektów S3, które chcesz usunąć (to znaczy, że nie jest zaprojektowana do obsługi czegoś takiego jak polityka przechowywania, pliki o określonym rozmiarze itp.).

Interfejs API REST S3 może określić do 1000 plików do usunięcia w jednym żądaniu, co musi być szybsze niż w przypadku pojedynczych żądań. Pamiętaj, że każde żądanie jest żądaniem HTTP (a więc TCP). Każde żądanie niesie więc koszty ogólne. Musisz tylko znać klucze obiektów i utworzyć żądanie HTTP (lub użyj opakowania w wybranym języku). AWS zapewnia świetne informacje na temat tej funkcji i jej użytkowania . Po prostu wybierz metodę, która najbardziej Ci odpowiada!

Zakładam, że twój przypadek użycia obejmuje użytkowników końcowych, którzy określają liczbę określonych plików do usunięcia na raz. Zamiast inicjować zadanie, takie jak „wyczyść wszystkie obiekty, które odnoszą się do plików obrazów” lub „wyczyść wszystkie pliki starsze niż określona data” (co moim zdaniem jest łatwe do skonfigurowania osobno w S3).

Jeśli tak, poznasz klucze, które musisz usunąć. Oznacza to również, że użytkownik będzie chciał otrzymywać w czasie rzeczywistym więcej informacji na temat tego, czy jego plik został pomyślnie usunięty, czy nie. Odniesienia do dokładnych kluczy powinny być bardzo szybkie, ponieważ S3 został zaprojektowany do wydajnego skalowania pomimo obsługi bardzo dużej ilości danych.

Jeśli nie, możesz przeglądać asynchroniczne wywołania API. Możesz przeczytać trochę o tym, jak ogólnie by działały, z tego postu na blogu lub poszukać, jak to zrobić w wybranym języku. Umożliwiłoby to zajęcie się żądaniem usunięcia własnego wątku, a reszta kodu może zostać wykonana bez oczekiwania użytkownika. Lub możesz odciążyć żądanie do kolejki. . . Ale obie te opcje niepotrzebnie komplikują albo twój kod (kod asynchroniczny może być denerwujący), albo twoje środowisko (potrzebujesz obsługi / demona / kontenera / serwera, aby obsłużyć kolejkę. Więc jeśli to możliwe, uniknę tego scenariusza.

Edycja: Nie mam reputacji, aby publikować więcej niż 2 linki. Ale komentarze Amazon dotyczące szybkości i wydajności żądań można znaleźć tutaj: http://docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html I s3 faq komentuje, że masowe deleiton jest droga, jeśli to możliwe.

Ed D'Azzo
źródło
19

Nieznośnie powolny rozwiązaniem jest s3 rm --recursive, jeśli rzeczywiście jak czekać.

Uruchamianie równoległe s3 rm --recursivez różnymi --includewzorami jest nieco szybsze, ale nadal dużo czasu czeka, ponieważ każdy proces indywidualnie pobiera całą listę kluczy, aby lokalnie wykonać --includedopasowanie wzorca.

Wprowadź usuwanie zbiorcze.

Odkryłem, że byłem w stanie uzyskać największą prędkość, usuwając 1000 kluczy jednocześnie aws s3api delete-objects.

Oto przykład:

cat file-of-keys | xargs -P8 -n1000 bash -c 'aws s3api delete-objects --bucket MY_BUCKET_NAME --delete "Objects=[$(printf "{Key=%s}," "$@")],Quiet=true"' _
  • -P8Opcja na xargskontroli równoległość. W tym przypadku jest osiem, co oznacza 8 wystąpień 1000 usunięć na raz.
  • -n1000Opcja mówi xargsdo bundle 1000 klucze dla każdego aws s3api delete-objectspołączenia.
  • Usunięcie ,Quiet=truelub zmiana na falsespowoduje wyrzucenie odpowiedzi serwera.
  • Uwaga: _na końcu tego wiersza poleceń łatwo można pominąć . @VladNikiforov opublikował doskonały komentarz na temat tego, do czego służy w komentarzu, więc zamierzam tylko link do tego.

Ale jak się masz file-of-keys?

Jeśli masz już listę kluczy, dobrze dla ciebie. Praca zakończona.

Jeśli nie, oto jeden ze sposobów:

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
antak
źródło
10
Świetne podejście, ale okazało się, że listowanie kluczy było wąskim gardłem. Jest to o wiele szybsze: aws s3api list-objects --output text --bucket BUCKET --query 'Contents[].[Key]' | pv -l > BUCKET.keys A następnie usuwanie obiektów (to wystarczyło, aby przejście przez 1 równoległy proces osiągnęło limity szybkości usuwania obiektów): 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
Prawdopodobnie powinieneś również podkreślić wagę na _końcu :) Przegapiłem to, a potem zajęło mi sporo czasu, aby zrozumieć, dlaczego pierwszy element jest pomijany. Chodzi o to, że bash -cprzekazuje wszystkie argumenty jako parametry pozycyjne, zaczynając od $0, podczas gdy „$ @” przetwarza tylko parametry zaczynające się od $1. Tak więc manekin podkreślający jest potrzebny do wypełnienia pozycji $0.
Vlad Nikiforov
@VladNikiforov Pozdrawiam, edytowane.
antak
3
Jednym z problemów, które znalazłem przy takim podejściu (od Antaka lub Vlada) jest to, że nie można go łatwo wznowić, jeśli wystąpi błąd. Jeśli usuwasz wiele kluczy (w moim przypadku 10M), możesz mieć błąd sieci lub błąd dławienia, który to psuje. Aby to poprawić, split -l 1000podzieliłem plik kluczy na 1000 partii kluczy. Teraz dla każdego pliku mogę wydać polecenie usuwania, a następnie usunąć plik. Jeśli coś pójdzie nie tak, mogę kontynuować.
joelittlejohn
Jeśli chcesz tylko listę wszystkich kluczy, pomyślałbym, że aws s3 ls "s3://MY_BUCKET_NAME/SOME_SUB_DIR" | awk '{print $4}'byłoby to prostsze i możesz dodać | grepdo tego filtr.
Hayden
3

Byłem sfrustrowany wydajnością konsoli internetowej do tego zadania. Odkryłem, że polecenie CLI AWS robi to dobrze. Na przykład:

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

W przypadku dużej hierarchii plików może to zająć sporo czasu. Możesz ustawić to w sesji tmuxlub screeni sprawdzić później.

Dannyman
źródło
2
Wygląda na to, że aws s3 rm --recursivepolecenie usuwa pliki pojedynczo. Chociaż jest szybszy niż konsola internetowa, podczas usuwania wielu plików może być znacznie szybszy, jeśli zostanie usunięty zbiorczo
Brandon
0

Nie wiedząc, jak zarządzasz segmentami s3, może to być szczególnie przydatne.

Narzędzia AWS CLI mają opcję o nazwie „synchronizacja”, która może być szczególnie skuteczna, aby upewnić się, że s3 ma właściwe obiekty. Jeśli Ty lub Twoi użytkownicy zarządzasz S3 z lokalnego systemu plików, możesz zaoszczędzić mnóstwo pracy, określając, które obiekty należy usunąć za pomocą narzędzi CLI.

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

Bill B.
źródło
0

Już wcześniej wspomniano o s3 syncpoleceniu, ale bez przykładu i słowa o --deleteopcji.

Znalazłem najszybszy sposób na usunięcie zawartości folderu w S3wiadrze my_bucketpoprzez:

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

Hubbitus
źródło