在 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 日的记录”。这样做需要扫描而不是查询,而且扫描是不可能的(考虑到我正在处理的数据量,速度慢得无法使用)
我不想交换分区键和排序键,原因有二:
- 处理要添加到 Dynamo 的新数据时 table,all 新 CDN 日志将在同一天.这意味着我的 table 将是不平衡的:一天内进行的每个写入操作都会命中相同的分区键
- 如果我想为单个客户提取一个月的数据,我将不得不进行 30 次查询 -- 每个月的每一天。当提取一年或 3 年的数据时,情况会变得更糟
我的第一个想法是“只需在 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 天。
我有一个 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 日的记录”。这样做需要扫描而不是查询,而且扫描是不可能的(考虑到我正在处理的数据量,速度慢得无法使用)
我不想交换分区键和排序键,原因有二:
- 处理要添加到 Dynamo 的新数据时 table,all 新 CDN 日志将在同一天.这意味着我的 table 将是不平衡的:一天内进行的每个写入操作都会命中相同的分区键
- 如果我想为单个客户提取一个月的数据,我将不得不进行 30 次查询 -- 每个月的每一天。当提取一年或 3 年的数据时,情况会变得更糟
我的第一个想法是“只需在 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 天。