我正在考虑使用DynamoDB来生成用户Feed。 我将使用PostId(Range)存储UserId(Hash)。但我需要在数据库中保留最后3000个帖子。所以我正在考虑有一个后台任务来清理表格。 这样做有道理吗?我不确定这种类型的范围查询是否能够合理地快速运行,因为我有大约25万个用户记录。
请建议可能有效的任何其他选项(redis中的扇出除外)。
答案 0 :(得分:5)
您的案例是一个典型的时间序列数据场景,随着时间的推移,您的记录将变得过时。您需要注意两个主要因素:
如果您将所有帖子放在一个表中,并且更频繁地访问最新的帖子,则无法有效使用预配置的吞吐量。 您应该将访问最多的项目分组到一个表中,以便可以针对所需的访问权限正确调整预配置的吞吐量。此外,请确保正确定义Hash Key that will allow even distribution of your data across multiple partitions。
文档建议将数据分段到不同的表中,以便在记录过时后删除或备份整个表(请参阅下面的详细信息)。
例如,您可以按月对表进行分段:
Posts_April, Posts_May, etc
或者通过Count,每个表包含最多记录数:
Posts_1, Posts_2, Posts_3, etc
在这种情况下,一旦当前的表达到最大记录数,就创建一个新表,并在需要进行清理时删除/备份最旧的表。
我可能需要一些有关您的用例的其他信息,以便为您提供有关如何利用此方法的更好示例。
在下面找到对以编程方式创建和删除表所需的操作的一些参考:
创建表格 http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_CreateTable.html
删除表格 http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DeleteTable.html
以下是解释与时间序列数据相关的最佳实践的文档部分:
了解时间序列数据的访问模式
对于您创建的每个表,指定吞吐量 要求。 DynamoDB分配和预留资源来处理您的 持续低延迟的吞吐量要求。当你设计 你的应用程序和表格,你应该考虑你的应用程序 访问模式,以最有效地使用您的表格 资源。
假设您设计了一个表来跟踪您网站上的客户行为, 例如他们点击的网址。您可以使用哈希和设计表 范围类型主键,客户ID作为哈希属性和 日期/时间作为范围属性。在此应用程序中,客户数据 随着时间的推移无限增长;但是,应用程序可能会显示 表格中所有项目的不均匀访问模式 最新的客户数据与您的应用程序可能更相关 随着时间的推移,更频繁地访问最新的项目 访问较少,最终很少访问旧项目。如果 这是一种已知的访问模式,您可以将其考虑在内 在设计表模式时。而不是存储所有项目 单个表,您可以使用多个表来存储这些项目。对于 例如,您可以创建表来存储月度或每周数据。对于 该表存储来自最近一个月或一周的数据,其中包含数据 访问速率很高,请求更高的吞吐量和表存储 较旧的数据,您可以调低吞吐量并节省资源。
您可以通过存储" hot"来节省资源。一个表中的项目 更高的吞吐量设置,"冷"另一个表中的项目 较低的吞吐量设置您只需删除即可删除旧项目 表格。您可以选择将这些表备份到其他存储 Amazon Simple Storage Service(Amazon S3)等选项。 正在删除 整个表比删除项目更有效 一个接一个,它基本上使您的写吞吐量翻倍 与put操作一样多的删除操作。
基于其他评论的更新答案:
"因此用户ID将成为我的哈希密钥。我需要的是清理程序......所以显然基于日期,单独的表方法将不会起作用,因为数据不是按时间帧而是按计数过滤的。在其他作品中,我需要为每个用户提供x个最近的记录。为了使它保持超过x的数量,我需要进行清理过程。"
在这种情况下,您几乎可以将Hash Key
定义为UserId
,将PostId
定义为Range Key
。
如果每个用户最多可以有10个帖子,则Range Key
最大值将为10.当您达到最大数量并且用户添加新帖子时,您将从1开始自动替换最旧的帖子来自该用户(有关详细信息,请参阅DynamoDB PutItem
操作)。最后,您只是为每个用户创建一个循环的帖子列表。
通过这样做,你实际上是在添加新帖子并通过一次写操作立即执行清理过程。
您可能需要创建一个支持表,其中包含每个PostId
发布的最后一个User
。如果您选择仅将哈希键定义为UserId
,则可以使用GetItem
操作(非常便宜且快速)查找特定用户的最后一个PostId。该表的模式可以简单如下:
UserId
(Hash Key
)
LastPostId
(数字属性) - 不是范围键
举个例子,假设你需要从UserId
= ABC
获取最近三个帖子:
第1步。在GetItem
上使用LastPostIds_Table
提供UserId (Hash Key) = "ABC"
如果LastPostId = 4
则
第2步。使用BatchGetItem
上的Posts_Table
获取UserId (Hash Key) = "ABC"
和PostId (Range Key) = 4, 3 and 2
的记录。
从返回的PostId
开始,您将知道4是最新的,2是最老的。
警告:使用BatchGetItem
返回多条记录may cause sudden bursts of reading activity。只需将读取操作分成几个较小的批次即可轻松解决此问题。
PutItem
有助于实现Post持久性逻辑:
<强> PutItem 强> 创建新项目,或用新项目替换旧项目。如果 与新项目具有相同主键的项目已存在于 在指定的表中,新项完全替换现有的 项目。您可以执行条件放置操作(如果是,则添加新项目) 一个指定的主键不存在),或替换一个 现有项目,如果它有某些属性值。
来源:http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html