我希望能够在 S3 上一次批量删除数千或数万个文件。每个文件的大小从 1MB 到 50MB 不等。当然,我不希望用户(或我的服务器)在文件删除过程中等待。因此,问题如下:
- S3 如何处理文件删除,尤其是删除大量文件时?
- 有没有一种有效的方法可以做到这一点并让 AWS 完成大部分工作?所谓高效,是指向 S3 发出最少的请求,花费最少的时间,使用服务器上最少的资源。
答案1
AWS 支持使用 S3 REST API 及其各种包装器每次请求批量删除最多 1000 个对象。此方法假定您知道要删除的 S3 对象键(也就是说,它不是为处理保留策略、超过一定大小的文件等而设计的)。
S3 REST API 可以在单个请求中指定最多 1000 个要删除的文件,这比发出单个请求要快得多。请记住,每个请求都是一个 HTTP(因此是 TCP)请求。因此每个请求都会产生开销。您只需知道对象的键并创建 HTTP 请求(或使用您选择的语言的包装器)。AWS 提供了有关此功能及其用法的大量信息。只需选择您最舒服的方法!
我假设您的用例涉及最终用户指定要一次删除的特定文件数量。而不是启动诸如“清除所有引用图片文件的对象”或“清除所有早于特定日期的文件”之类的任务(我相信在 S3 中很容易单独配置这些任务)。
如果是这样,您就会知道需要删除哪些键。这也意味着用户会喜欢更多有关其文件是否成功删除的实时反馈。对确切键的引用应该非常快,因为 S3 被设计为尽管处理大量数据也能有效扩展。
如果没有,您可以研究异步 API 调用。您可以从这里了解它们的一般工作原理博客文章或者用你选择的语言搜索如何做到这一点。这将允许删除请求占用自己的线程,其余代码可以执行而无需用户等待。或者,你可以将请求卸载到队列中……但这两个选项都会不必要地复杂化你的代码(异步代码可能很烦人)或你的环境(你需要一个服务/守护进程/容器/服务器来处理队列)。所以如果可能的话,我会避免这种情况。
编辑:我没有发布超过 2 个链接的声誉。但您可以在此处查看亚马逊对请求率和性能的评论:http://docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html并且 s3 常见问题解答评论说,如果可能的话,批量删除是可行的方法。
答案2
这极其缓慢选择是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
onxargs
控制并行度。在本例中为 8,即每次删除 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
答案3
一个巧妙的技巧是使用生命周期规则来为您处理删除。您可以排队规则以删除您想要的前缀或对象,Amazon 只会处理删除。
https://docs.aws.amazon.com/AmazonS3/latest/user-guide/create-lifecycle.html
答案4
我对这个任务的 Web 控制台的性能感到失望。我发现AWS CLI命令可以很好地完成这一点。例如:
aws s3 rm --recursive s3://my-bucket-name/huge-directory-full-of-files
对于较大的文件层次结构,这可能需要相当长的时间。您可以将其设置为在tmux
或screen
会话中运行,然后稍后再检查。