Cara paling efisien untuk menghapus file S3 secara batch


16

Saya ingin dapat menghapus ribuan atau puluhan ribu file sekaligus di S3. Setiap file akan berkisar dari 1MB hingga 50MB. Secara alami, saya tidak ingin pengguna (atau server saya) menunggu sementara file sedang dalam proses dihapus. Oleh karena itu, pertanyaannya:

  1. Bagaimana S3 menangani penghapusan file, terutama ketika menghapus sejumlah besar file?
  2. Apakah ada cara yang efisien untuk melakukan ini dan membuat AWS melakukan sebagian besar pekerjaan? Secara efisien, maksud saya dengan membuat jumlah permintaan paling sedikit ke S3 dan mengambil jumlah waktu paling sedikit menggunakan sumber daya paling sedikit di server saya.

Jawaban:


12

AWS mendukung penghapusan massal hingga 1000 objek per permintaan menggunakan API S3 REST dan berbagai pembungkusnya. Metode ini mengasumsikan Anda tahu kunci objek S3 yang ingin Anda hapus (yaitu, itu tidak dirancang untuk menangani sesuatu seperti kebijakan penyimpanan, file yang melebihi ukuran tertentu, dll).

S3 REST API dapat menentukan hingga 1000 file yang akan dihapus dalam satu permintaan, yang mana harus lebih cepat daripada membuat permintaan individual. Ingat, setiap permintaan adalah permintaan HTTP (dengan demikian TCP). Jadi setiap permintaan memiliki overhead. Anda hanya perlu mengetahui kunci objek dan membuat permintaan HTTP (atau menggunakan pembungkus dalam bahasa pilihan Anda). AWS memberikan informasi hebat tentang fitur ini dan penggunaannya . Pilih saja metode yang paling nyaman bagi Anda!

Saya berasumsi kasus penggunaan Anda melibatkan pengguna akhir yang menentukan sejumlah file tertentu untuk dihapus sekaligus. Daripada memulai tugas seperti "membersihkan semua objek yang merujuk ke file gambar" atau "bersihkan semua file yang lebih tua dari tanggal tertentu" (yang saya percaya mudah untuk dikonfigurasikan secara terpisah dalam S3).

Jika demikian, Anda akan tahu kunci yang perlu Anda hapus. Ini juga berarti pengguna akan lebih suka umpan balik waktu nyata tentang apakah file mereka berhasil dihapus atau tidak. Referensi ke kunci yang tepat seharusnya sangat cepat, karena S3 dirancang untuk mengukur secara efisien meskipun menangani sejumlah besar data.

Jika tidak, Anda dapat melihat panggilan API asinkron. Anda dapat membaca sedikit tentang cara kerjanya secara umum dari posting blog ini atau mencari cara melakukannya dalam bahasa pilihan Anda. Ini akan memungkinkan permintaan penghapusan untuk mengambil utasnya sendiri, dan sisa kode dapat dijalankan tanpa membuat pengguna menunggu. Atau, Anda dapat menurunkan permintaan ke antrian. . . Tetapi kedua opsi ini tidak perlu mempersulit kode Anda (kode asinkron bisa mengganggu) atau lingkungan Anda (Anda memerlukan layanan / daemon / container / server untuk menangani antrian. Jadi saya akan menghindari skenario ini jika memungkinkan.

Sunting: Saya tidak memiliki reputasi untuk mengirim lebih dari 2 tautan. Tetapi Anda dapat melihat komentar Amazon pada tingkat permintaan dan kinerja di sini: http://docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html Dan komentar faq s3 bahwa deleiton massal adalah cara untuk pergi jika mungkin.


17

Opsi yang sangat lambat adalah s3 rm --recursivejika Anda benar-benar suka menunggu.

Menjalankan paralel s3 rm --recursivedengan --includepola yang berbeda sedikit lebih cepat tetapi banyak waktu masih dihabiskan menunggu, karena setiap proses secara individual mengambil seluruh daftar kunci untuk melakukan --includepencocokan pola secara lokal .

Masukkan penghapusan massal.

Saya menemukan saya bisa mendapatkan kecepatan paling banyak dengan menghapus 1000 kunci sekaligus aws s3api delete-objects.

Ini sebuah contoh:

cat file-of-keys | xargs -P8 -n1000 bash -c 'aws s3api delete-objects --bucket MY_BUCKET_NAME --delete "Objects=[$(printf "{Key=%s}," "$@")],Quiet=true"' _
  • The -P8pilihan pada xargskontrol paralelisme. Ini delapan dalam hal ini, yang berarti 8 contoh 1000 penghapusan sekaligus.
  • The -n1000pilihan memberitahu xargsbundel 1000 kunci untuk setiap aws s3api delete-objectspanggilan.
  • Menghapus ,Quiet=trueatau mengubahnya falseakan memuntahkan respons server.
  • Catatan: Ada yang mudah terjawab _di akhir baris perintah itu. @VladNikiforov memposting komentar yang bagus tentang apa artinya dalam komentar jadi saya akan tautkan saja ke sana.

Tapi bagaimana caranya file-of-keys?

Jika Anda sudah memiliki daftar kunci Anda, bagus untuk Anda. Pekerjaan selesai.

Jika tidak, inilah satu cara yang saya kira:

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
Pendekatan yang bagus, tetapi saya menemukan bahwa daftar kunci adalah hambatan. Ini jauh lebih cepat: aws s3api list-objects --output text --bucket BUCKET --query 'Contents[].[Key]' | pv -l > BUCKET.keys Dan kemudian menghapus objek (ini cukup bahwa melewati 1 proses paralel mencapai batas laju untuk penghapusan objek): 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
Anda mungkin juga harus menekankan pentingnya pada _akhirnya :) Saya melewatkannya dan butuh waktu cukup lama untuk memahami mengapa elemen pertama dilewati. Intinya adalah yang bash -cmeneruskan semua argumen sebagai parameter posisi, dimulai dengan $0, sementara "$ @" hanya memproses parameter yang dimulai dengan $1. Jadi dummy garis bawah diperlukan untuk mengisi posisi $0.
Vlad Nikiforov

@VladNikiforov Cheers, diedit.
antak

3
Satu masalah yang saya temukan dengan pendekatan ini (baik dari antak atau Vlad) adalah bahwa itu tidak mudah dilanjutkan jika ada kesalahan. Jika Anda menghapus banyak kunci (10 juta dalam kasus saya), Anda mungkin memiliki kesalahan jaringan, atau kesalahan pelambatan, yang merusak ini. Jadi untuk meningkatkan ini, saya sudah terbiasa split -l 1000membagi file kunci saya menjadi 1000 batch kunci. Sekarang untuk setiap file saya dapat mengeluarkan perintah delete kemudian menghapus file. Jika ada yang salah, saya bisa melanjutkan.
joelittlejohn

Jika Anda hanya ingin daftar al kunci, saya akan berpikir aws s3 ls "s3://MY_BUCKET_NAME/SOME_SUB_DIR" | awk '{print $4}'akan lebih sederhana dan Anda dapat menambahkan | grepuntuk menyaring yang turun dari sana.
Hayden

3

Saya merasa frustrasi dengan kinerja konsol web untuk tugas ini. Saya menemukan bahwa perintah AWS CLI melakukan ini dengan baik. Sebagai contoh:

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

Untuk hierarki file besar, ini mungkin membutuhkan waktu yang cukup lama. Anda dapat mengatur ini berjalan dalam satu tmuxatau screensesi dan periksa kembali nanti.


2
Sepertinya aws s3 rm --recursiveperintah menghapus file satu per satu. Meskipun lebih cepat daripada konsol web, ketika menghapus banyak file, bisa jauh lebih cepat jika dihapus secara massal
Brandon


0

Tanpa mengetahui bagaimana Anda mengelola bucket s3, ini mungkin bermanfaat atau tidak.

Alat AWS CLI memiliki opsi yang disebut "sinkronisasi" yang dapat sangat efektif untuk memastikan s3 memiliki objek yang benar. Jika Anda, atau pengguna Anda, mengelola S3 dari sistem file lokal, Anda mungkin dapat menghemat banyak pekerjaan menentukan objek mana yang perlu dihapus dengan menggunakan alat CLI.

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


0

Sudah disebutkan tentang s3 syncperintah sebelumnya, tetapi tanpa contoh dan kata tentang --deleteopsi.

Saya menemukan cara tercepat untuk menghapus konten folder dalam S3ember my_bucketdengan:

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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.