Cách hiệu quả nhất để xóa hàng loạt tệp S3


16

Tôi muốn có thể xóa hàng loạt hoặc hàng chục nghìn tệp cùng một lúc trên S3. Mỗi tệp sẽ có giá trị từ 1MB đến 50MB. Đương nhiên, tôi không muốn người dùng (hoặc máy chủ của tôi) chờ trong khi các tệp đang trong quá trình xóa. Do đó, các câu hỏi:

  1. Làm thế nào để S3 xử lý việc xóa tệp, đặc biệt là khi xóa số lượng lớn tệp?
  2. Có cách nào hiệu quả để làm điều này và khiến AWS thực hiện hầu hết công việc không? Theo hiệu quả, ý tôi là bằng cách thực hiện số lượng yêu cầu ít nhất cho S3 và dành ít thời gian nhất bằng cách sử dụng ít tài nguyên nhất trên máy chủ của tôi.

Câu trả lời:


12

AWS hỗ trợ xóa hàng loạt lên tới 1000 đối tượng cho mỗi yêu cầu bằng API S3 REST và các trình bao bọc khác nhau của nó. Phương pháp này giả định rằng bạn biết các khóa đối tượng S3 mà bạn muốn xóa (nghĩa là nó không được thiết kế để xử lý một cái gì đó như chính sách lưu giữ, các tệp có kích thước nhất định, v.v.).

API S3 REST có thể chỉ định tối đa 1000 tệp sẽ bị xóa trong một yêu cầu, điều này phải nhanh hơn so với thực hiện các yêu cầu riêng lẻ. Hãy nhớ rằng, mỗi yêu cầu là một yêu cầu HTTP (do đó TCP). Vì vậy, mỗi yêu cầu mang trên đầu. Bạn chỉ cần biết các khóa của đối tượng và tạo một yêu cầu HTTP (hoặc sử dụng trình bao bọc trong ngôn ngữ bạn chọn). AWS cung cấp thông tin tuyệt vời về tính năng này và cách sử dụng . Chỉ cần chọn phương pháp bạn cảm thấy thoải mái nhất!

Tôi giả sử trường hợp sử dụng của bạn liên quan đến người dùng cuối chỉ định một số tệp cụ thể cần xóa cùng một lúc. Thay vì bắt đầu một tác vụ như "thanh lọc tất cả các đối tượng tham chiếu đến tệp ảnh" hoặc "lọc tất cả các tệp cũ hơn một ngày nhất định" (mà tôi tin là dễ dàng cấu hình riêng trong S3).

Nếu vậy, bạn sẽ biết các phím mà bạn cần xóa. Điều đó cũng có nghĩa là người dùng sẽ thích phản hồi theo thời gian thực hơn về việc liệu tệp của họ có bị xóa thành công hay không. Tham chiếu đến các khóa chính xác được cho là rất nhanh, vì S3 được thiết kế để mở rộng hiệu quả mặc dù xử lý một lượng dữ liệu cực lớn.

Nếu không, bạn có thể xem xét các lệnh gọi API không đồng bộ. Bạn có thể đọc một chút về cách họ làm việc nói chung từ bài đăng trên blog này hoặc tìm kiếm cách thực hiện bằng ngôn ngữ bạn chọn. Điều này sẽ cho phép yêu cầu xóa lấy chủ đề của chính nó và phần còn lại của mã có thể thực thi mà không khiến người dùng phải chờ đợi. Hoặc, bạn có thể giảm yêu cầu đến hàng đợi. . . Nhưng cả hai tùy chọn này đều không làm phức tạp mã của bạn (mã không đồng bộ có thể gây khó chịu) hoặc môi trường của bạn (bạn cần một dịch vụ / daemon / container / máy chủ để xử lý hàng đợi. Vì vậy, tôi nên tránh trường hợp này.

Chỉnh sửa: Tôi không có danh tiếng để đăng nhiều hơn 2 liên kết. Nhưng bạn có thể xem các nhận xét của Amazon về tỷ lệ yêu cầu và hiệu suất tại đây: http://docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html Và các bình luận s3 faq mà deleiton hàng loạt là cách để đi nếu có thể.


17

Các excruciatingly chậm tùy chọn là s3 rm --recursivenếu bạn thực sự thích chờ đợi.

Chạy song song s3 rm --recursivevới --includecác mẫu khác nhau sẽ nhanh hơn một chút nhưng vẫn còn rất nhiều thời gian chờ đợi, vì mỗi quy trình tìm nạp riêng toàn bộ danh sách khóa để thực hiện --includekhớp mẫu cục bộ .

Nhập số lượng lớn xóa.

Tôi thấy rằng tôi có thể đạt được tốc độ cao nhất bằng cách xóa 1000 phím cùng một lúc bằng cách sử dụng aws s3api delete-objects.

Đây là một ví dụ:

cat file-of-keys | xargs -P8 -n1000 bash -c 'aws s3api delete-objects --bucket MY_BUCKET_NAME --delete "Objects=[$(printf "{Key=%s}," "$@")],Quiet=true"' _
  • Các -P8tùy chọn trên xargskiểm soát song song. Đó là tám trong trường hợp này, có nghĩa là 8 trường hợp xóa 1000 lần một lần.
  • Các -n1000tùy chọn cho xargsbó 1000 phím cho mỗi aws s3api delete-objectscuộc gọi.
  • Loại bỏ ,Quiet=truehoặc thay đổi nó falsesẽ phun ra phản ứng của máy chủ.
  • Lưu ý: Có một lỗi dễ bị bỏ lỡ _ở cuối dòng lệnh đó. @VladNikiforov đã đăng một bài bình luận tuyệt vời về những gì nó được bình luận vì vậy tôi sẽ chỉ liên kết đến đó.

Nhưng làm thế nào để bạn có được file-of-keys?

Nếu bạn đã có danh sách các phím của bạn, tốt cho bạn. Công việc hoàn thành.

Nếu không, đây là một cách tôi đoán:

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
Cách tiếp cận tuyệt vời, nhưng tôi thấy rằng việc liệt kê các khóa là nút cổ chai. Việc này nhanh hơn nhiều: aws s3api list-objects --output text --bucket BUCKET --query 'Contents[].[Key]' | pv -l > BUCKET.keys Và sau đó xóa các đối tượng (điều này là đủ để vượt qua 1 quá trình song song đạt đến giới hạn tốc độ để xóa đối tượng): 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
Có lẽ bạn cũng nên nhấn mạnh tầm quan trọng _cuối cùng :) Tôi đã bỏ lỡ nó và sau đó tôi mất khá nhiều thời gian để hiểu tại sao yếu tố đầu tiên bị bỏ qua. Vấn đề là bash -cvượt qua tất cả các đối số dưới dạng tham số vị trí, bắt đầu bằng $0, trong khi "$ @" chỉ xử lý các tham số bắt đầu bằng $1. Vì vậy, hình nộm gạch dưới là cần thiết để điền vào vị trí của $0.
Vlad Nikiforov

@VladNikiforov Chúc mừng, đã chỉnh sửa.
antak

3
Một vấn đề tôi đã tìm thấy với phương pháp này (từ antak hoặc Vlad) là nó không dễ dàng phục hồi nếu có lỗi. Nếu bạn đang xóa rất nhiều khóa (trong trường hợp của tôi là 10 triệu), bạn có thể gặp lỗi mạng hoặc lỗi điều chỉnh, sẽ phá vỡ điều này. Vì vậy, để cải thiện điều này, tôi đã sử dụng split -l 1000để chia tệp khóa của mình thành 1000 lô khóa. Bây giờ đối với mỗi tệp tôi có thể ban hành lệnh xóa sau đó xóa tệp. Nếu có gì sai, tôi có thể tiếp tục.
joelittlejohn

Nếu bạn chỉ muốn danh sách các khóa, tôi nghĩ aws s3 ls "s3://MY_BUCKET_NAME/SOME_SUB_DIR" | awk '{print $4}'sẽ đơn giản hơn và bạn có thể thêm một | grepđể lọc từ đó xuống.
Hayden

3

Tôi đã thất vọng bởi hiệu suất của giao diện điều khiển web cho nhiệm vụ này. Tôi thấy rằng lệnh AWS CLI thực hiện tốt điều này. Ví dụ:

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

Đối với hệ thống phân cấp tệp lớn, việc này có thể mất một lượng thời gian đáng kể. Bạn có thể thiết lập chạy này trong một tmuxhoặc screenphiên và kiểm tra lại sau.


2
Có vẻ như aws s3 rm --recursivelệnh xóa các tệp riêng lẻ. Mặc dù nhanh hơn bảng điều khiển web, nhưng khi xóa nhiều tệp, nó có thể nhanh hơn nhiều nếu xóa hàng loạt
Brandon


0

Không biết bạn đang quản lý các thùng s3 như thế nào, điều này có thể hoặc không đặc biệt hữu ích.

Các công cụ AWS CLI có một tùy chọn gọi là "đồng bộ hóa" có thể đặc biệt hiệu quả để đảm bảo s3 có các đối tượng chính xác. Nếu bạn hoặc người dùng của bạn đang quản lý S3 từ hệ thống tệp cục bộ, bạn có thể lưu một tấn công việc xác định đối tượng nào cần xóa bằng cách sử dụng các công cụ CLI.

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


0

Đã có đề cập về s3 synclệnh trước đó, nhưng không có ví dụ và từ về --deletetùy chọn.

Tôi tìm thấy cách nhanh nhất để xóa nội dung của thư mục trong S3nhóm my_bucketbằng cách:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.