DynamoDB是否适合作为S3元数据索引?



我想存储和查询大量的原始事件数据。我想使用的架构是"数据湖"架构,其中S3保存实际的事件数据,DynamoDB用于索引它并提供元数据。这是一个在很多地方都被讨论和推荐的架构:

  • https://aws.amazon.com/blogs/big-data/building-and-maintaining-an-amazon-s3-metadata-index-without-servers/
  • https://www.youtube.com/watch?v=7Px5g6wLW2A
  • https://s3.amazonaws.com/big-data-ipc/AWS_Data-Lake_eBook.pdf

然而,我正在努力理解如何使用DynamoDB来查询S3中的事件数据。在上面指向AWS博客的链接中,他们使用了存储由多个不同服务器生成的客户事件的示例:

S3路径格式:[4-digit hash]/[server id]/[year]-[month]-[day]-[hour]-[minute]/[customer id]-[epoch timestamp].data

例如:a5b2/i-31cc02/2015-07-05-00-25/87423-1436055953839.data

在DynamoDB中记录此事件的模式如下:

Customer ID (Partition Key), Timestamp-Server (Sort Key), S3-Key, Size
87423, 1436055953839-i-31cc02, a5b2/i-31cc02/2015-07-05-00-25/87423-1436055953839.data, 1234

我想执行这样的查询:"获取所有服务器在过去24小时内产生的所有客户事件",但据我所知,如果不使用分区键,就不可能有效地查询DynamoDB。我不能为这种查询指定分区键。

考虑到这个要求,我应该使用DynamoDB以外的数据库来记录我的事件在S3中的位置吗?还是只需要使用不同类型的DynamoDB模式?

使用DynamoDB数据库,体系结构看起来很好且可行。DynamoDBMapper类(存在于AWS SDK Java中)可用于创建具有从S3获取数据的有用方法的模型。

DynamoDBMapper

getS3ClientCache()返回用于访问的底层S3ClientCacheS3 .

如果没有分区键,DynamoDB数据库无法查询。如果分区键不可用,则必须扫描整个DynamoDB数据库。但是,您可以在日期/时间字段上创建全局二级索引(GSI),并为您的用例查询数据。

简单来说,GSI类似于任何RDBMS中的索引。不同之处在于,您可以直接查询GSI而不是主表。通常,如果您希望在分区键不可用时查询DynamoDB,则需要GSI。在GSI中,有一些选项可以包含所有(或)存在于主表中的可选字段。

全球二级指数(GSI)

DynamoDB中Scan和Query的区别

是的,在这个用例中,看起来GSI无法提供帮助,因为用例需要对分区键进行RANGE查询。DynamoDB只支持相等操作符。如果分区键可用,DynamoDB支持对排序键或其他非键属性进行范围查询。您可能需要扫描DynamoDB来完成这个用例,这是一个昂贵的操作。

您可以考虑使用分区键查询或使用其他数据库的替代数据模型。

首先,我也读过同一个AWS博客页面:https://aws.amazon.com/blogs/big-data/building-and-maintaining-an-amazon-s3-metadata-index-without-servers/

使用DynamoDB实现此功能的唯一方法是:

  • 添加另一个名为"foo"的属性,并为所有项目设置相同的值1
  • 添加另一个名为"timestamp"的属性,并将epoch时间戳放在那里
  • 用分区键"foo"和范围键"timestamp"创建一个GSI,并投影所有其他属性

看起来有点脏,是吧?然后,您可以使用分区键1(所有项目都有1)查询最近24小时的项目,并使用该时间戳范围键。现在,问题:

  1. GSI具有相同分区键的所有项目?如果数据增长很大,性能会很差
  2. 使用GSI成本更高

你也应该考虑成本。想想你的数据摄取率。每秒将1000个对象放入桶中每月将花费600美元,使用GSI则要多花费600美元。仅仅因为这个查询需求(过去24小时),你必须多花600美元。

我在设计这个元数据索引时遇到了同样的问题。DynamoDB看起来不太对劲。当您尝试以使用RDBMS的方式使用DynamoDB时,您总是会得到这样的结果。因为我很少有像你这样的查询需求。我考虑过ElasticSearch和s3 listing river插件,它们看起来也不太好,因为我必须管理ES集群和存储。CloudSearch呢?考虑到它的局限性,CloudSearch也不合适。

我的要求:

  1. 能够访问具有给定前缀的最近对象
  2. 能够访问特定时间范围内的对象
  3. 在AWS EMR、Athena或红移光谱的键空间中通过散列字符串获得S3的最大性能

我完全迷路了。我甚至考虑过S3版本控制功能,因为我可以很自然地获得最新的对象。似乎一切都不太对,AWS文档和博客文章充满了困惑。

这就是我整个星期被困的地方:(

AWS的人就是喜欢画图表。当他们介绍一些新的架构方案或概念时,他们只是在那里放一堆AWS产品图标,说它集成得很漂亮。

最新更新