从DynamoDB中删除大量项目的build议方法是什么?
我在DynamoDB中编写了一个简单的日志logging服务。
我有一个由user_id散列和timestamp(Unix纪元int)范围键入的日志表。
当服务的用户终止他们的帐户,我需要删除表中的所有项目,无论范围值。
做这种操作的推荐方式是什么(记住可能有数百万个项目要删除)?
就我所见,我的select是:
答:执行扫描操作,调用每个退回的项目的删除,直到没有项目剩下
B:执行BatchGet操作,再次调用每个项目的删除,直到没有剩余
这两个对我来说都很糟糕,因为他们需要很长时间。
我最想做的就是调用LogTable.DeleteItem(user_id) – 不提供范围,并删除所有的东西。
我最想做的就是调用LogTable.DeleteItem(user_id) – 不提供范围,并删除所有对我来说。
确实可以理解的要求; 我可以想象,AWS团队可能会随着时间的推移增加这些高级操作(他们有先从有限的function集开始,根据客户反馈评估扩展的历史),但是这里应该做些什么来避免成本一个完整的扫描至less:
-
使用查询而不是扫描检索
user_id
所有项目 – 无论使用的组合散列/范围主键是什么 , 这都是有效的,因为HashKeyValue和RangeKeyCondition是这个API中的独立参数,而前者只是针对复合主键。 。- 请注意,您将不得不像往常一样处理查询API分页,请参阅ExclusiveStartKey参数:
要从其中继续先前查询的项目的主键。 如果在完成查询之前查询操作被中断,则较早的查询可能会将此值作为LastEvaluatedKey提供; 无论是因为结果集大小还是Limit参数。 LastEvaluatedKey可以传回一个新的查询请求,以继续从这一点的操作。
- 请注意,您将不得不像往常一样处理查询API分页,请参阅ExclusiveStartKey参数:
-
遍历所有返回的项目,并像往常一样简化DeleteItem
- 更新 :很可能BatchWriteItem更适合于这样的用例(详见下文)。
更新
正如ivant所强调的那样 , BatchWriteItem操作使您能够在单个API调用中放置或删除多个表中的多个项目[我的重点] :
要上传一个项目,您可以使用PutItem API并删除一个项目,您可以使用DeleteItem API。 但是,如果要上传或删除大量数据(如从Amazon Elastic MapReduce(EMR)上载大量数据或将数据从另一个数据库迁移到Amazon DynamoDB中),则此API提供了一种有效的select。
请注意,这仍然有一些相关的限制,最显着的是:
-
单个请求中的最大操作 – 您可以指定总共多达25个放置或删除操作; 但是,总请求大小不能超过1 MB(HTTP有效负载)。
-
不是primefaces操作 – 在BatchWriteItem中指定的单个操作是primefaces操作; 但是BatchWriteItem作为一个整体是一个“尽力而为”的操作,而不是一个primefaces操作。 也就是说,在一个BatchWriteItem请求中,一些操作可能会成功,而另一些可能会失败。 […]
尽pipe如此,这显然为手头上的用例带来了潜在的重大收益。
根据DynamoDB文档,您可以删除整个表。
见下文:
“删除整个表格比逐个删除项目效率更高,这实际上是写入吞吐量的两倍,因为您执行了与放置操作一样多的删除操作”
如果您只想删除一部分数据,那么您可以为每个月,每年或类似情况制作单独的表格。 这样你可以删除“上个月”,并保持其余的数据不变。
以下是使用AWS SDK在Java中删除表的方法:
DeleteTableRequest deleteTableRequest = new DeleteTableRequest() .withTableName(tableName); DeleteTableResult result = client.deleteTable(deleteTableRequest);
这个问题的答案取决于物品的数量,尺寸和预算。 取决于我们有以下三种情况:
1-表中项目的数量和大小不是很多。 那么作为Steffen欧宝说,你可以使用查询,而不是扫描检索所有项目user_id,然后循环所有返回的项目,并促进DeleteItem
或BatchWriteItem
。 但请记住,在这里可能会消耗大量的吞吐量。 例如,考虑您需要从DynamoDB表中删除1000个项目的情况。 假设每个项目的大小都是1 KB,则会产生大约1MB的数据。 这个批量删除任务将需要总共2000个写入容量单位进行查询和删除。 要在10秒内执行此数据加载(在某些应用程序中甚至没有将其视为快速),您需要将表的预置写入吞吐量设置为200个写入容量单位。 正如你可以看到它可以使用这种方式,如果它的less数项目或小尺寸项目。
2-表中有很多物品或很大的物品,我们可以根据时间将它们存储在不同的表格中。 然后乔纳森说,你可以删除表格。 这是好多了,但我不认为这是匹配你的情况。 由于您要删除所有用户数据,无论创build日志的时间是多less,所以在这种情况下,您无法删除特定的表。 如果你想每个用户都有一张单独的桌子,那么我猜如果用户数量很多,那么这么贵,这对你的情况是不实际的。
3-如果你有很多数据,你不能把你的冷热数据分成不同的表格,而且你需要频繁地进行大规模的删除,不幸的是,DynamoDB对你来说不是一个好的select。 它可能会变得更昂贵或非常慢(取决于您的预算)。 在这些情况下,我build议为您的数据find另一个数据库。