在 DynamoDB 中按排序键索引?

Indexing by sort key in DynamoDB?

我有一个 DynamoDB table,我在其中聚合 CDN 访问日志。具体我想跟踪:

For a given customer (all of whose requests can be identified from the URL being downloaded), how many bytes were delivered on their behalf each day?

我在 customer 上有一个主分区键,在 time_bucket 上有一个主排序键(天)。这样,给定一个客户,我可以说“查找从 2021 年 3 月 1 日到 2021 年 3 月 31 日的所有记录”。到目前为止,还不错

当我想开始删除旧数据时出现了问题。超过 5 年的任何内容都应从数据库中删除。

因为分区键 不是 time_bucket,没有简单的方法可以说“检索 all 2016 年 5 月 25 日的记录”。这样做需要扫描而不是查询,而且扫描是不可能的(考虑到我正在处理的数据量,速度慢得无法使用)

我不想交换分区键和排序键,原因有二:

我的第一个想法是“只需在 time_bucket 列上添加一个索引”,但是当我尝试这样做时出现错误:

Attribute Name is duplicated: time_bucket (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: PAN9FVSEMBBJT412NCV013VURNVV4KQNSO5AEMVJF66Q9ASUAAJG; Proxy: null)

DynamoDB 似乎不允许您在排序键上创建索引。那么这里的正确解决方案是什么?

正确的处理方法是在将记录放入 DDB 时简单地设置 5 年 TTL

记录不仅会自动删除,而且删除是免费的。没有消耗 WCU。

您现在可以添加 TTL,但您将不得不组装一个小实用程序来为现有记录添加过期时间属性。

如果您想手动执行此操作,则需要添加全球二级索引 (GSI)。您可以使用现有的 timebucket 作为 GSI 哈希键。那么你会 Query(GSI, hk='2016-05-01') 查找记录和 DeleteItem() 为每一个。

请注意,GSI 有其自身的成本,您需要付费阅读 GSI 并从 table 中删除。

DynamoDB 是一个 NoSQL 数据库,允许快速 Lookup 操作,而不是分析性操作,例如提取一整月的数据。您可能可以以一种或另一种方式做到这一点,但您不应该这样做。 将您的记录从 DDB 复制到 S3(使用 DynamoDB Streams 和 Kinesis Firehose 作为无服务器选项),然后使用 Amazon Athena 查询数据。您将获得一个成本极低且可扩展的丰富分析 SQL 界面。您不需要无缘无故地删除旧数据。它还会降低您的 DynamoDB 成本,因为您可以仅将查找所需的数据存储在那里,例如 30 天。