如何从DynamoDB中删除大量项目是推荐的方式?

13 浏览
0 Comments

如何从DynamoDB中删除大量项目是推荐的方式?

我正在DynamoDB中编写一个简单的日志记录服务。

我有一个按用户ID哈希和时间戳(Unix epoch int)范围分区键的日志表。

当服务的用户终止他们的帐户时,我需要删除表中的所有项目,无论范围值如何。

如何推荐执行这种操作(请记住可能有数百万个项目需要删除)?

就我能看到,我的选项有:

A:执行扫描操作,在每个返回项目上调用删除,直到没有项目为止

B:执行批处理获取操作,再次在每个项目上调用删除,直到没有项目为止

这两种方法都对我来说看起来很糟糕,因为它们需要很长时间。

我理想情况下想要做的是调用LogTable.DeleteItem(user_id)-而不提供范围,然后让它为我删除所有内容。

admin 更改状态以发布 2023年5月23日
0
0 Comments

根据DynamoDB文档,您只需删除整个表即可。如下所示:

“删除整个表比逐个删除项目更高效,因为您执行的删除操作数量等于放入操作,从而将写入吞吐量翻倍。”

如果您只想删除数据子集,则可以为每个月、每年或类似的项制作单独的表。这样,您可以删除“上个月”,并保留其余数据完好无损。

以下是使用AWS SDK在Java中删除表的方法:

DeleteTableRequest deleteTableRequest = new DeleteTableRequest()
  .withTableName(tableName);
DeleteTableResult result = client.deleteTable(deleteTableRequest);

0
0 Comments

我的理想情况是调用LogTable.DeleteItem(user_id)时不必提供范围参数,它能够自动删除所有内容。

这是一个可以理解的请求,我可以想象AWS团队可能随着时间推移会增加这样的高级操作(他们有一个历史,首先从有限的功能集开始并根据客户反馈评估扩展),但是至少可以避免全面扫描的成本,以下是您应该做的:

  1. 使用查询而不是扫描来检索所有user_id的项目 - 这适用于使用组合哈希/范围主键的情况,因为HashKeyValue和RangeKeyCondition在此API中是单独的参数,并且前者仅针对复合主键的哈希组件的属性值..

    • 请注意,您通常需要处理查询API分页,参见ExclusiveStartKey参数:

      从其中继续较早查询的项的主键。如果查询操作由于结果集大小或Limit参数而中断,则较早的查询可能将此值作为LastEvaluatedKey提供。 LastEvaluatedKey可以在新的查询请求中传递回来以从该点继续操作。

  2. 循环遍历所有返回的项目,并像通常一样使用DeleteItem

    • 更新:像这种用例最适用的方法可能是BatchWriteItem(有关详细信息,请参见下文)。

更新

正如ivant所提出的,BatchWriteItem操作可以使您在单个API调用中放置或删除多个表中的多个项目 [我的强调]:

要上传一个项目,您可以使用PutItem API,要删除一个项目,可以使用DeleteItem API。但是,当您要上传或删除大量数据时,例如从Amazon Elastic MapReduce(EMR)上传大量数据或将数据从另一个数据库迁移到Amazon DynamoDB中,此API提供了一种有效的替代方法。

请注意,这仍然有一些相关的限制,尤其是:

  • 单个请求中的最大操作数 - 您可以指定最多25个put或delete操作; 但是,总请求大小不能超过1 MB (HTTP负载)。

  • 不是原子操作 - 在BatchWriteItem中指定的单个操作是原子的; 但整个BatchWriteItem是一种"尽力而为"的操作,而不是原子操作。也就是说,在BatchWriteItem请求中,某些操作可能成功,而其他操作可能失败。[...]

尽管如此,这显然对像这样的用例产生了潜在的显著收益。

0