如何快速查找与AWS S3存储桶中的模式匹配的密钥?

时间:2016-03-11 13:29:45

标签: scala amazon-web-services amazon-s3 apache-spark

我做了以下的事情,以便在我的水桶中找到模式

def getListOfPrefixesFromS3(dataPath: String, prefix: String, delimiter: String, batchSize: Integer): List[String] = {
    var s3Client = new AmazonS3Client()
    var listObjectsRequest = new ListObjectsRequest().withBucketName(dataPath).withMaxKeys(batchSize).withPrefix(prefix).withDelimiter(delimiter)
    var objectListing: ObjectListing = null
    var res: List[String] = List()

    do {
      objectListing = s3Client.listObjects(listObjectsRequest)
      res = res ++ objectListing.getCommonPrefixes
      listObjectsRequest.setMarker(objectListing.getNextMarker)
    } while (objectListing.isTruncated)
    res
  }

对于较大的存储桶,由于所有对象摘要都是由Aws返回的,而不仅仅是与前缀和分隔符匹配的对象摘要,因此会消耗太多时间。我正在寻找提高性能的方法,到目前为止我只发现我应该为密钥命名并将它们妥善组织在桶中。

如果有人能指出我正确的方向,或者给我一个提示,那将是非常有用的,无论它多么小可能会非常好。

我正在使用java sdk for AWS,这段代码在一个spark作业中运行,主要是在scala中。

编辑1:因为我正在使用火花。我开始做的是找到带有分隔符的键作为" /"。这给了我很多常见的前缀或说顶级文件夹。然后我用,

sc.parallelize(keys).map(key => getListOfPrefixesForKey(key))

获取所有密钥的列表。我希望通过充分的并行化,这将加速为我搜索密钥。由于我无法移动数据或对其进行重组,我认为这是我的唯一途径。

任何人都可以添加如何更有效地使用spark找到密钥?

1 个答案:

答案 0 :(得分:1)

S3不提供随机访问密钥查找功能 - 除非您的对象密钥具有语义含义且可以通过前缀定位,否则没有内置功能允许索引搜索。

许多AWS服务专注于其核心竞争力,并且不提供与不同AWS服务可用功能重叠的功能。这是一个例子。

  

一个常见的解决方案是构建一个将可查询属性映射到S3对象键的外部索引。

这是official AWS Blog Post引用该主题的引用。

  

此索引可以利用为快速查找而构建的数据存储库,但可能不太适合存储大型数据blob。

举例来说:在我的环境中,我用于此目的的解决方案之一是RDS上的MariaDB,它维护受监视桶中所有密钥的索引 - 以及所有对象版本,用于版本化桶 - 以及所有对象属性(大小,日期,etag)和元数据,它们也是索引和可搜索的。数据库由S3事件自动更新,这些事件将进入SQS队列,并在那里进行处理。

但我并不是说这是The One True Way™。

没有一种正确的方法 - 有许多技术非常适合这种应用。 S3事件通知功能允许自动近乎实时地维护索引,维护索引的代码可以在EC2中运行,也可以使用Lambda运行无服务器。

上面链接的博文解释了如何使用DynamoDB执行此操作。