【问题标题】:AWS-SDK S3 list big directories failAWS-SDK S3 列出大目录失败
【发布时间】:2012-10-22 19:24:22
【问题描述】:

在 AWS-SDK 中,它列出了以下形式的 ruby​​ 代码:

 s3 = AWS::S3.new
 bucket = s3.buckets[bucket_name]
 tree = bucket.as_tree(:prefix => 'myshop/products')
 directories = tree.children.select(&:branch?).collect(&:prefix)

失败错误:“无法在 S3 列表对象响应中找到标记”

目录结构

/myshop/products/1474472/original.jpg
/myshop/products/1474472/small.jpg
/myshop/products/1474472/mini.jpg
/myshop/products/1333333/original.jpg
/myshop/products/1333333/small.jpg
/myshop/products/1333333/mini.jpg

...

超过 100 000 个对象

我想验证目录(例如“1474472”)是否已创建

我的计划:aws-s3-list-> ruby​​-array->在数组中查找 (array.include?)

!!!需要非常快速的方法 - 世界末日即将来临 :)

【问题讨论】:

  • 我不熟悉 Ruby SDK,但 S3 只允许您一次列出 1000 个对象,因此列出 100,000 个对象将导致至少 100 个 HTTP 请求。如果您想检查特定对象是否存在,那么为该对象发送 HEAD 请求是最好的方法。听起来您想检查一个或多个文件是否与给定前缀匹配,难道您不能只调整现有的前缀搜索以包含子目录名称吗?
  • 嗨,aws ping 需要 288 毫秒 - 0.3 秒 х 10000= 3000 秒 = 50 分钟,时间很长。

标签: ruby amazon-s3 aws-sdk


【解决方案1】:

Amazon S3 中没有文件夹之类的东西。它是一个“平面”文件系统。看看this answer

您真正需要的是验证给定前缀(例如“/myshop/products/1474472”)是否存在于您的存储桶中。
他们的 REST API 绝对支持它,看看the documentation。您需要列出与给定prefix 匹配的键(即“文件名”),这些键可以作为参数传递。您还可以通过将max-keys 参数设置为1 来优化您的呼叫。这样,如果您在响应中收到任何非零数量的项目,则存储桶已包含名称以给定前缀开头的文件。

【讨论】:

    【解决方案2】:
    aws s3 cp s3://bucket/tmp/foo/ . --recursive --exclude "*" --include "*1474472" 
    

    https://docs.aws.amazon.com/cli/latest/reference/s3/index.html#use-of-exclude-and-include-filters

    【讨论】:

      【解决方案3】:

      理想的方法是在写入 S3 时通过您的应用程序维护列表。 EMRFS 通过将详细信息存储在 Dynamo DB 上来做同样的事情。

      使用列表生成清单,例如对于 S3Distcp。这样我们就可以避免将 S3 打到 list,这是一个代价高昂的操作。

      【讨论】:

        猜你喜欢
        • 2016-10-08
        • 2022-11-03
        • 2017-10-27
        • 2015-08-31
        • 1970-01-01
        • 2021-10-27
        • 1970-01-01
        • 1970-01-01
        • 2018-12-24
        相关资源
        最近更新 更多