rest - 多线程的可能算法列出大型 S3 存储桶中的所有键?

标签 rest amazon-s3 concurrent-programming

在包含大量键的 S3 存储桶中,通过 REST api 列出键是一个非常缓慢的过程,因为

  • 您一次只能列出 1000 个键。
  • 确定第 5001 个键(据我所知)的唯一方法是列出前 1000 个键,根据响应中的下一个标记列出下一个,然后递归直到到达 5001。
  • S3 REST api 请求的延迟非常高,请求 1000 个键通常需要几秒钟。

  • 鉴于发出 100 个并发 key 列表 REST 请求不应减慢任何单个请求的速度,否则此过程将通过并行化进行优化。但是,如果我的算法是“愚蠢的”并且只是将可能的 key 空间拆分为预定义的标记(例如,''、'a'、'b'、'c'、'd'、'e' ... ) 它不会真正加快在每个键都以“images/”开头的存储桶中列出键的速度

    所以我想知道是否有真正有过 S3 经验的人知道一种更好的方法来遍历存储桶的 key 空间,或者是否有人尝试过使用自适应(即“不愚蠢”)算法来改进具有并发性的 key 列表。

    最佳答案

    也许某种形式的“二分搜索”算法会有所帮助? EG 以前缀 '' 和 'm' 开头,然后是一半,等等。我认为你最终会得到每个键最多两次左右 - 当你已经有了“nextmarker”时,你就不再需要更多了。

    如何选择多少开始?我想也许在每个周期分割:启动 '' 然后当这些结果回来时,如果 '' 结果指示更多键,则在该搜索中启动 'nextmarker' 加上在 'nextmarker' 和 'z' 中间的新搜索.重复。使用类似哈希的东西只存储一次所有的键。

    由于所有请求都来自不同的线程等,因此您需要锁定以添加所有键。然后你会遇到保持锁打开的问题,不会减慢速度,所以这取决于你使用的语言等。

    如果您的进程在与 S3 文件位于同一区域的 EC2 实例上运行,您可能能够更快地完成此操作。假设文件在美国“标准”中。那么你很幸运,你可以使用 ruby​​ 和类似 Ironworker 的东西进入那里并下载所有的 key 。完成后,它可以发布到您的服务器,或在 S3 上创建一个文件,该文件是所有 key 的列表,或类似的文件。对于不同的区域或语言,您可能需要启动自己的 EC2 实例。

    我发现 S3 key 列表在 EC2 实例上要快得多,因为每个请求都有大量带宽(您无需在 EC2 上为此付费)。 S3 不会对响应进行 gzip 压缩,这是非常松散的 XML,因此您和 S3 之间的带宽至关重要。

    关于rest - 多线程的可能算法列出大型 S3 存储桶中的所有键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8782793/

    相关文章:

    java - 多线程方面比较java和scala

    javascript - 浏览器中的JavaScript是否可能发生并发读/写读/写冲突?

    java - 在 Java Restful API JSON 结果字符串上获取意外的额外转义字符

    javascript - Angular 组件和后端服务之间的通信

    upload - Amazon S3 的 HTTP 上传功能是否支持 web-hook 样式回调?

    python - 从 S3 django 下载多个文件

    multithreading - 在函数式编程中如何避免副作用

    spring - 为什么 Spring RestTemplate 在 Spring 中默认不是 Bean?

    php - CSRF 和 RESTful API(symfony2,php)

    amazon-web-services - `aws s3 cp` 与 `aws s3 sync` 行为和成本