在AWS S3中选择随机对象

时间:2017-10-23 01:05:58

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

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

3 个答案:

答案 0 :(得分:3)

如果您知道对象键(文件名),那么这是一个很容易解决的问题。即使您不知道前面的文件名,也可以通过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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

由于您还需要保持“访问状态”,因此可以使用一个跟踪文件元数据的DynamoDB表。

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