【问题标题】:Possible algorithm for multithreading listing all keys in a large S3 bucket?多线程列出大型 S3 存储桶中所有密钥的可能算法?
【发布时间】:2012-01-10 22:02:50
【问题描述】:

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

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

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

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

【问题讨论】:

  • 由于 S3 返回大型 XML - 未压缩 - 您将只用几个请求淹没您的 Internet 连接,这当然取决于您的连接和程序的速度。
  • 我将通过列出每个级别的键并使用线程沿着树向下移动来使用这里的机制。它也可能对你有用。 stackoverflow.com/questions/1239700/…
  • @TomAndersen 4 年后才看到这一点。我挑战你用 S3 存储桶列表请求使 ec2 实例带宽(100 mbps)饱和,哈哈。
  • 我可以使连接饱和 - 限制是 #of IOP,即针对特定前缀,所有客户端每秒读取 5,500 次。您不需要超过几十个激进的 EC2 客户端,因为它们都得到 503,您必须退缩。如果您在树上行走,请在返回的路径中取光,并在潜入它们之前随机化。

标签: rest amazon-s3 concurrent-programming


【解决方案1】:

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

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

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

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

我发现在 EC2 实例上列出 S3 密钥要快得多,因为每个请求都有大量带宽(您无需在 EC2 上付费)。 S3 不会压缩响应,这些响应是超级蓬松的 XML,因此您和 S3 之间的带宽至关重要。

【讨论】:

  • 谢谢。我不认为二进制搜索方法比仅仅提前细分理论键空间更好,因为如果键密集地聚集在“images/”下,那么每批与末尾的距离或多或少相同。关键空间。当然,从 EC2 实例发出的请求具有更低的延迟/更高的吞吐量,但我真正想要的是一种算法,它可以优化任何密钥遍历,而不管这些超出其控制范围的因素。我认为使用前缀和分隔符来伪造广度优先遍历是有希望的,但需要更多的思考。
猜你喜欢
  • 1970-01-01
  • 2017-05-25
  • 2015-10-23
  • 1970-01-01
  • 2018-08-28
  • 2014-07-18
  • 2011-03-21
  • 2012-04-12
  • 1970-01-01
相关资源
最近更新 更多