Amazon dynamodb DynamoDB中的排序键索引?

Amazon dynamodb DynamoDB中的排序键索引?,amazon-dynamodb,Amazon Dynamodb,我有一个DynamoDB表,我在其中聚合CDN访问日志。我特别想跟踪: 对于给定的客户(其所有请求都可以从正在下载的URL中识别),每天代表他们发送多少字节 我在customer上有一个主分区键,在time\u bucket(day)上有一个主排序键。这样,对于一位客户,我可以说“查找2021年3月1日至2021年3月31日的所有记录”。到目前为止,一切顺利 当我想开始删除旧数据时,问题就出现了。任何超过5年的数据都应该从数据库中删除 由于分区键不在时间段上,因此没有简单的方法说“检索2016年

我有一个DynamoDB表,我在其中聚合CDN访问日志。我特别想跟踪:

对于给定的客户(其所有请求都可以从正在下载的URL中识别),每天代表他们发送多少字节

我在
customer
上有一个主分区键,在
time\u bucket
(day)上有一个主排序键。这样,对于一位客户,我可以说“查找2021年3月1日至2021年3月31日的所有记录”。到目前为止,一切顺利

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

由于分区键不在
时间段
上,因此没有简单的方法说“检索2016年5月25日的所有记录”。这样做需要扫描而不是查询,而且扫描是不可能的(考虑到我处理的数据量,速度非常慢)

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

  • 在处理要添加到Dynamo表中的新数据时,所有新CDN日志将在同一天使用。这意味着我的表将是不平衡的:在一天内进行的每个写操作都将命中相同的分区键
  • 如果我想为一个客户提取一个月的数据,我必须进行30次查询——每月每天查询一次。如果提取一年或三年的数据,情况会更糟
我的第一个想法是“只需在
time\u bucket
列上添加一个索引”,但当我尝试这样做时,我遇到了一个错误:

属性名称重复:time_bucket(服务:AmazonDynamoDBv2;状态代码:400;错误代码:ValidationException;请求ID:PAN9FVSEMBBJT412NCV013VURNVV4KQNSO5AEMVJF66Q9ASUAAJG;代理:null)


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

正确的处理方法是,在将记录放入DDB时,只需在记录上设置一个5年

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

您现在可以添加TTL,但您必须组合一个小实用程序,向现有记录添加过期时间属性

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


请注意,GSI有它自己的成本,您需要支付读取GSI并从表中删除的费用。

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

我们不是查询原始数据,而是聚合数据。这就是为什么迪纳摩感觉是个不错的选择。雅典娜是伟大的当你想查询原始数据。在我们的例子中,每当一个新的CloudFront日志到达S3时,我们触发一个Lambda,它将日志文件解析为100个左右的“更新”操作,以更新客户消耗的总字节的运行总和。在一般用例中,我们会进行查找(对于给定的客户,对于给定的日期,查找总字节的总和),这是非常高效、快速和便宜的。只有当我们想要删除数据时,我们才会遇到一个非常有意义的问题。上面提到的DDB记录的生存时间(TTL)选项应该可以满足您的需要。制作GSI是我试图做的(您会注意到我说过我试图在Time_bucket上创建一个“索引”——我应该是具体的,意思是我正在创建一个分区键为Time_bucket的全局二级索引)迪纳摩队犯了一个错误。因此,本文试图找出如何在排序键上生成GSI,因为我得到了一个“属性名已存在”错误。奇怪的是,在刷新页面时,我能够尝试创建相同的索引,但没有得到错误。我认为今天早上web UI处于一种奇怪的状态。。。