【问题标题】:Select random object in AWS S3在 AWS S3 中选择随机对象
【发布时间】:2017-10-23 22:23:44
【问题描述】:

我有一个包含大约 10,000 个图像对象的 AWS S3 存储桶。我想使用boto3 来随机获取一个对象。 list_objects_v2() 一次只列出 1,000 个对象,但允许您分页。我的问题是我目前正在考虑的方法是否是最好的方法。我打算对每个对象列表进行分页,将每个页面中的所有键保存到一个列表中。在没有剩余页面后,从列表中随机选择一个键。

【问题讨论】:

  • 虽然该方法可行,但还有其他方法可以在 S3 中生成对象的密钥吗?我想这取决于你必须多久重新生成一次列表,但你描述的是一个昂贵的操作。但是,例如,如果您知道文件名都是 IMG + [0-9999] + .jpg 或其他任何名称,则无需读取列表即可生成密钥。只是一个想法。
  • @stdunbar 我看到的问题是,虽然我知道所有文件名,但是在我访问一个对象后,我将它从存储桶中删除。所以我必须跟踪我已经访问过的文件。
  • 你还有第二个问题,@IsiahL。 (第一个:这会很慢而且成本太高。)您不能假设已删除的对象会立即从后续的列表对象结果中消失。您可能需要考虑解释为什么要选择一个随机对象然后将其删除。您也可能忽略了其他问题。
  • @Michael-sqlbot 所以基本上这只是一个个人有趣的项目,用于制作一个每 2 小时左右发布一张图片的 twitter 机器人。本来打算用 Lambda 来做,成本低,工作量少,只觉得用 S3 存储图片才有意义。如果你有更好的方法请告诉我!
  • @IsiahL S3 存储和提供图片是有意义的。 S3 随机选择它们是没有意义的。您需要将图片列表存储在其他地方,以可以轻松随机查询的形式。在 S3 上存储文件但在数据库、缓存或搜索引擎中存储对它们的引用是一种非常常见的模式。

标签: amazon-web-services amazon-s3 boto3


【解决方案1】:

如果您知道对象键(文件名),那么解决问题就很容易了。即使您不知道前面的文件名,您也可以通过list_objects_v2() 分页来构建对象列表。

保留文件名列表,将其随机播放并逐个弹出。

import random

mykeys = [objj1, obj2, ....] # or build this list by paginating
random.shuffle(mykeys)
while mykeys:
  random_key = mykeys.pop()
  print random_key

另一种选择是使用random.choice

import random

mykeys = [objj1, obj2, ....] # or build this list by paginating
while mykeys:
  random_key = random.choice(mykeys)
  mykeys.remove(random_key)
  print random_key

【讨论】:

    【解决方案2】:

    由于您希望在随机选择每个对象后删除它,因此我会将所有对象键预加载到 ElastiCache Redis 缓存中。这会给你一个fast method of retrieving a random key。这将比您提议的对 S3 的 boto3 调用快很多倍,可以安全地与多个并发进程一起使用,并且您可以确定一旦从 Redis 中删除一个密钥,它就不会在后续调用中返回(与 S3 不同)。

    【讨论】:

    • 如果我没看错,ElastiCache 节点是否一直在运行?无论如何在我的 lambda 进程中启动和停止它?我不想为这个项目支付很多费用,而且每隔几个小时 24/7 运行几秒钟似乎没有必要。
    • ElastiCache 需要一个服务器,我认为它无法停止。您可以改为在 EC2 实例上运行 Redis 服务器,并在需要时停止/启动它。不过,您一定要配置 Redis 来持久化数据库。
    【解决方案3】:

    由于您还需要保留已访问状态,因此您可以使用 DynamoDB 表来跟踪文件的元数据。

    • 您可以使用 S3 触发器和 Lambda 在 Dynamodb 中创建项目。
    • 对于属性,选择S3 Key(文件名)作为Hash key,normal属性存储一个Flag来跟踪它是否被访问,另一个属性存储一个随机数。
    • 使用随机数作为哈希键和访问标志作为范围键创建 GSI。
    • 在您的查询中,您只需要在其范围内生成一个随机数,并在 Accessed Flag 为 false 的情况下进行查询。如果返回项目,您可以将 Flag 更新为 true。如果没有再次查询生成一个新的随机数。
    • 在此选择适当范围的随机数(例如 1 到 2 或 1 到 5 或 1 到 10)以减少您希望对查询执行的平均重试次数非常重要。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-01
      • 2015-07-15
      • 2012-11-01
      相关资源
      最近更新 更多