【问题标题】:Is DynamoDB suitable as an S3 Metadata index?DynamoDB 是否适合作为 S3 元数据索引?
【发布时间】:2017-03-24 16:05:18
【问题描述】:

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

但是,我很难理解如何使用 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 数据库。如果分区键不可用,您必须扫描整个 DynamoDB。另一种方法是在日期时间字段上创建全局二级索引。
  • @notionquest 谢谢。您能否详细说明全球二级索引的含义以及它对这里的帮助?
  • 使用elasticsearch索引元数据怎么样?看看下面的链接:indexing-metadata-in-amazon-elasticsearch-service-using-aws-lambda-and-python

标签: amazon-s3 amazon-dynamodb data-lake


【解决方案1】:

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

DynamoDBMapper

getS3ClientCache() 返回底层 S3ClientCache 用于访问 S3.

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

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

Global Secondary Index (GSI)

Difference between Scan and Query in DynamoDB

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

您已经考虑过替代数据模型,您可以在其中通过分区键查询或使用其他数据库。

【讨论】:

  • GSI 文档说:“每个全局二级索引都必须有一个分区键,并且可以有一个可选的排序键。”我认为这意味着它不会解决使用时间范围有效检索记录的问题?
  • 在上述用例中,Timestamp-Server 应该是 GSI 的分区键。
  • 如果我使用时间戳作为分区键,那么我在查询索引时还需要为其指定一个值。同样,来自文档:“您需要指定索引名称、索引分区键和排序键(如果存在)的查询条件”。这是否意味着我不能进行有效的范围查询?
  • 同意,GSI 在这里帮不上忙。更新了我的答案。
【解决方案2】:

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

使用 DynamoDB 进行这项工作的唯一方法是:

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

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

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

您还应该考虑成本。考虑一下您的数据摄取率。每秒将 1000 个对象放入存储桶中的成本约为每月 600 美元,而使用 GSI 则多 600 美元。仅仅因为查询需求(过去 24 小时),您就必须多花 600 美元。

我在设计这个元数据索引时遇到了同样的问题。 DynamoDB 看起来不太对劲。当您尝试以使用 RDBMS 的方式使用 DynamoDB 时,总是会遇到这种情况。因为我很少有像你这样的查询需求。我想到了 ElasticSearch 和 s3 列表河插件,它看起来也不好看,因为我必须管理 ES 集群和存储。云搜索呢?看看它的极限,CloudSearch 也没有落到正确的位置。

我的要求:

  1. 能够访问具有给定前缀的最新对象
  2. 能够访问特定时间范围内的对象
  3. 通过在 AWS EMR、Athena 或 Redshift Spectrum 的密钥空间中散列字符串来获得 S3 的最大性能

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

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

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

【讨论】:

  • 我什至考虑将纪元时间戳作为二进制数格式放入对象键中。例如4238429332 就像“111011010101010101010101”。然后您可以获得带有特定前缀的 LIST,这将为您提供特定的时间范围。你猜怎么了? S3 获取 LIST 请求比 DynamoDB 读取配置价格贵得多。如果你能以某种方式将结果全部使用到 1000 个对象的限制,那可能是有道理的,但那不是我的情况。
  • 看起来 AWS 正在为 S3 开发一项新功能。有一个名为“S3 索引团队”的团队正在招聘...amazon.jobs/en/jobs/468608
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-21
  • 2020-01-31
  • 2018-11-24
  • 2021-11-24
  • 2020-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多