批删除S3文件的最有效方法


16

我希望能够在S3上一次批量删除成千上万个文件。每个文件的大小在1MB到50MB之间。自然,我不希望用户(或我的服务器)在删除文件过程中等待。因此,问题是:

  1. S3如何处理文件删除,尤其是在删除大量文件时?
  2. 是否有一种有效的方法来做到这一点,并使AWS能够完成大部分工作?所谓高效,是指对S3的请求数量最少,并使用服务器上最少的资源花费最少的时间。

Answers:


12

AWS使用S3 REST API及其各种包装器,支持每个请求最多删除1000个对象。此方法假定您知道要删除的S3对象键(即,它不旨在处理诸如保留策略,文件超过一定大小等)。

S3 REST API可以在单个请求中最多指定1000个要删除的文件,这比发出单个请求要快。请记住,每个请求都是一个HTTP(因此是TCP)请求。因此,每个请求都会带来开销。您只需要知道对象的键并创建HTTP请求(或使用您选择的语言使用包装器)即可。AWS提供了有关此功能及其用法的重要信息。只需选择最舒适的方法即可!

我假设您的用例涉及最终用户指定要立即删除的多个特定文件。而不是启动诸如“清除所有引用图片文件的对象”或“清除早于某个特定日期的所有文件”之类的任务(我相信在S3中易于单独配置)。

如果是这样,您将知道需要删除的密钥。这也意味着用户希望获得有关是否成功删除其文件的更多实时反馈。假定对精确键的引用非常快,因为尽管处理了大量数据,但S3旨在有效地扩展。

如果没有,您可以查看异步API调用。您可以从此博客文章中大致了解它们的工作原理,或者搜索以您选择的语言进行操作的方式。这将允许删除请求占用其自己的线程,并且其余代码可以执行而无需用户等待。或者,您可以将请求卸载到队列中。。。但是这两个选项都不必要使您的代码(异步代码可能很烦人)或您的环境(您需要一个服务/守护程序/容器/服务器来处理队列)复杂化,因此,如果可能的话,我会避免这种情况。

编辑:我没有声誉发布两个以上的链接。但是您可以在这里看到亚马逊对请求率和性能的评论:http : //docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html以及s3常见问题评论,即批量删除是可行的方式。


17

速度奇慢的选择是s3 rm --recursive,如果你真的喜欢等待。

s3 rm --recursive与不同--include模式并行运行会稍快一些,但仍要花费大量时间,因为每个进程都会单独获取整个键列表,以便本地执行--include模式匹配。

输入批量删除。

我发现通过使用一次删除1000个键可以使速度最快aws s3api delete-objects

这是一个例子:

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上选项xargs控制并行性。在这种情况下为八个,这意味着一次删除1000次的8个实例。
  • -n1000选项告诉xargs您为每个aws s3api delete-objects呼叫捆绑1000个密钥。
  • ,Quiet=true将其删除或更改为false将发出服务器响应。
  • 注意:_该命令行末尾很容易错过。@VladNikiforov在评论中对它的用途发表了出色的评论,因此我将直接链接到该评论。

但是你怎么得到的file-of-keys

如果您已经有了钥匙列表,那么对您有好处。工作完成。

如果没有,我猜这是一种方法:

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
好的方法,但是我发现列出密钥是瓶颈。这快得多: aws s3api list-objects --output text --bucket BUCKET --query 'Contents[].[Key]' | pv -l > BUCKET.keys 然后删除对象(这足以使经过1个并行过程达到对象删除的速率限制): 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
最后,您可能还应该强调它的重要性_:)我错过了它,然后花了我相当长的时间才能理解为什么第一个元素被跳过。关键是bash -c将所有参数作为位置参数以开头$0,而“ $ @”仅处理以开头的参数$1。因此,需要使用下划线假人来填充的位置$0
弗拉德·尼基福罗夫

@VladNikiforov干杯,已编辑。
安塔克

3
我发现这种方法(来自antak或Vlad)的一个问题是,如果有错误,就不容易恢复。如果要删除很多密钥(在我的情况下为10M),则可能是网络错误或节流错误,这会破坏此错误。因此,为了改善这一点,我曾经split -l 1000将我的密钥文件分为1000个批次。现在,对于每个文件,我可以发出delete命令,然后删除该文件。如果有任何问题,我可以继续。
joelittlejohn

如果您只想列出所有键,我想aws s3 ls "s3://MY_BUCKET_NAME/SOME_SUB_DIR" | awk '{print $4}'会更简单,您可以添加一个| grep从此处过滤掉它。
海登

3

Web控制台执行此任务的性能使我感到沮丧。我发现AWS CLI命令可以很好地完成此任务。例如:

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

对于大型文件层次结构,这可能需要花费大量时间。您可以将此设置运行在tmuxscreen会话中,然后稍后再查看。


2
看起来该aws s3 rm --recursive命令会分别删除文件。尽管比Web控制台快,但是在删除大量文件时,如果将其批量删除,则可能会快得多
Brandon


0

在不知道如何管理s3存储桶的情况下,这可能会或可能不会特别有用。

AWS CLI工具具有一个称为“ sync”的选项,该选项对于确保s3具有正确的对象特别有效。如果您或您的用户正在从本地文件系统管理S3,则可以使用CLI工具节省大量工作来确定需要删除哪些对象。

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


0

s3 sync之前已经提到过命令,但是没有示例和关于--delete选项的字眼。

我发现通过以下方式删除S3存储桶中文件夹内容的最快方法my_bucket

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.