S3 dosyalarını toplu silmek için en etkili yolu


16

S3'te bir seferde binlerce veya on binlerce dosyayı toplu olarak silmek istiyorum. Her dosya 1MB ile 50MB arasında herhangi bir yerde olabilir. Doğal olarak, dosyaları (veya sunucumu) dosyaları silinme işlemi sırasında beklemek istemiyorum. Dolayısıyla, sorular:

  1. S3, özellikle çok sayıda dosyayı silerken dosya silme işlemini nasıl gerçekleştirir?
  2. Bunu yapmanın ve AWS'nin işin çoğunu yapmasının etkili bir yolu var mı? Verimli olarak, yani S3'e en az sayıda istekte bulunarak ve sunucularımdaki en az miktarda kaynağı kullanarak en az zaman alarak.

Yanıtlar:


12

AWS, S3 REST API'sini ve çeşitli sarmalayıcılarını kullanarak istek başına 1000 nesneye kadar toplu silme işlemini destekler. Bu yöntem, kaldırmak istediğiniz S3 nesne anahtarlarını bildiğinizi varsayar (yani, saklama politikası, belirli bir boyutun üzerindeki dosyalar vb.) İşlemek için tasarlanmamıştır.

S3 REST API'si, tek bir istekte silinecek 1000 adede kadar dosya belirtebilir ve bu da bireysel isteklerde bulunmaktan daha hızlıdır. Unutmayın, her istek bir HTTP (dolayısıyla TCP) isteğidir. Böylece her istek yükü taşır. Sadece nesnelerin anahtarlarını bilmeniz ve bir HTTP isteği oluşturmanız (veya kendi dilinizde bir sarmalayıcı kullanmanız) yeterlidir. AWS, bu özellik ve kullanımı hakkında harika bilgiler sağlar . Sadece en rahat olduğunuz yöntemi seçin!

Kullanım durumunuzun, bir kerede silinecek belirli dosyaları belirleyen son kullanıcıları içerdiğini varsayıyorum. "Resim dosyalarına atıfta bulunan tüm nesneleri temizle" veya "belirli bir tarihten daha eski tüm dosyaları temizle" (S3'te ayrıca yapılandırmanın kolay olduğuna inanıyorum) gibi bir görevi başlatmak yerine.

Öyleyse, silmeniz gereken anahtarları bilirsiniz. Ayrıca, kullanıcının dosyalarının başarılı bir şekilde silinip silinmediği hakkında daha fazla gerçek zamanlı geri bildirim isteyeceği anlamına gelir. Kesin tuşlara yapılan atıfların çok hızlı olması gerekiyordu, çünkü S3 son derece büyük miktarda veri işlemesine rağmen verimli bir şekilde ölçeklenmek üzere tasarlandı.

Değilse, eşzamansız API çağrılarına bakabilirsiniz. Bu blog gönderisinden genel olarak nasıl çalışacakları hakkında biraz okuyabilir veya istediğiniz dilde nasıl yapılacağını arayabilirsiniz. Bu, silme isteğinin kendi iş parçacığını almasına izin verir ve kodun geri kalanı bir kullanıcıyı bekletmeden yürütülebilir. Veya isteği bir kuyruğa yükleyebilirsiniz. . . Ancak bu seçeneklerin her ikisi de kodunuzu (eşzamansız kod can sıkıcı olabilir) veya ortamınızı (kuyruğu işlemek için bir hizmet / daemon / container / server gerekir) gereksiz yere karmaşık hale getirir.

Düzenleme: 2'den fazla bağlantı yayınlamak için bir üne sahip değilim. Ama burada istek oranı ve performansa Amazon'un yorumları görebilirsiniz: http://docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html Ve s3 sss yorumlar toplu deleiton olduğunu mümkünse gitmek için bir yol.


19

Son derece yavaş olan seçenek s3 rm --recursiveaslında beklemeyi seviyorsanız.

s3 rm --recursiveFarklı --includedesenlerle paralel çalışmak biraz daha hızlıdır, ancak her işlem --includedesen eşleştirmesini yerel olarak gerçekleştirmek için tüm anahtar listesini tek tek getirdiği için beklemek için çok zaman harcanır .

Toplu silme işlemini girin.

Bir seferde 1000 anahtarı silerek en yüksek hızı elde edebildiğimi fark ettim aws s3api delete-objects.

İşte bir örnek:

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Üzerinde seçenek xargskontrolleri paralellik. Bu durumda sekiz, yani bir seferde 1000 silme 8 örneği.
  • Bu -n1000seçenek, xargsher aws s3api delete-objectsçağrı için 1000 anahtar paketlemesini söyler .
  • ,Quiet=trueBunu kaldırmak veya değiştirmek falsesunucu yanıtlarını ortaya çıkaracaktır.
  • Not: _Komut satırının sonunda kolayca gözden kaçırılabilir . @VladNikiforov yorumda bunun ne için mükemmel bir yorum gönderdi , bu yüzden sadece bağlantı vereceğim.

Ama nasıl elde edersin file-of-keys?

Anahtar listeniz zaten varsa, sizin için iyi. İş tamamlandı.

Değilse, sanırım bir yolu:

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
Harika bir yaklaşım, ama anahtarları listeleme darboğaz olduğunu buldum. Bu çok daha hızlı: aws s3api list-objects --output text --bucket BUCKET --query 'Contents[].[Key]' | pv -l > BUCKET.keys Ve sonra nesneleri kaldırmak (1 paralel işlemden geçmenin nesne silme için hız sınırlarına ulaşması yeterliydi): 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
Muhtemelen _sonunda önemini de vurgulamış olmalısın :) Bunu kaçırdım ve sonra ilk elementin neden atlandığını anlamak biraz zaman aldı. Buradaki nokta, bash -ctüm argümanları ile başlayan konumsal parametreler olarak geçerken $0, "$ @" sadece ile başlayan parametreleri işler $1. Yani alt çizgi kukla konumunu doldurmak için gereklidir $0.
Vlad Nikiforov

@VladNikiforov Şerefe düzenlendi.
antak

3
Bu yaklaşımla bulduğum bir sorun (antak veya Vlad'tan), bir hata varsa kolayca sürdürülemez olmasıdır. Çok sayıda anahtar siliyorsanız (benim durumumda 10M), bir ağ hatası veya kısıtlama hatasıyla karşılaşabilirsiniz. Bunu geliştirmek için, split -l 1000anahtarlarımı 1000 anahtar grubuna ayırdım. Şimdi her dosya için delete komutunu verebilirim ve sonra dosyayı silebilirim. Bir şeyler ters giderse, devam edebilirim.
joelittlejohn

Sadece anahtarların tüm listesini istiyorsanız, aws s3 ls "s3://MY_BUCKET_NAME/SOME_SUB_DIR" | awk '{print $4}'daha basit olacağını düşünürdüm ve | greporadan filtre uygulamak için bir ekleyebilirsiniz .
Hayden

3

Bu görev için web konsolunun performansı beni hayal kırıklığına uğrattı. AWS CLI komutunun bunu iyi yaptığını gördüm . Örneğin:

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

Büyük bir dosya hiyerarşisi için bu oldukça uzun sürebilir. Bunu bir oturumda tmuxveya screenoturumda ayarlayabilir ve daha sonra tekrar kontrol edebilirsiniz.


2
aws s3 rm --recursiveKomut dosyaları tek tek siler gibi görünüyor . Web konsolundan daha hızlı olmasına rağmen, çok sayıda dosyayı silerken, toplu olarak silinirse çok daha hızlı olabilir
Brandon


0

S3 kovalarını nasıl yönettiğinizi bilmeden, bu özellikle yararlı olabilir veya olmayabilir.

AWS CLI araçları, s3'ün doğru nesnelere sahip olmasını sağlamak için özellikle etkili olabilecek "senkronizasyon" adlı bir seçeneğe sahiptir. Siz veya kullanıcılarınız S3'ü yerel bir dosya sisteminden yönetiyorsanız, CLI araçlarını kullanarak hangi nesnelerin silinmesi gerektiğini belirleyen bir ton çalışma kaydedebilirsiniz.

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


0

Daha s3 syncönce komuttan bahsedilmişti , ancak --deleteseçenek hakkında örnek ve kelime yok .

S3Kovadaki klasör içeriğini silmenin en hızlı yolunu buldum my_bucket:

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.