DB中的用户提要(可能是DynamoDb)

时间:2015-04-22 01:04:13

标签: amazon-web-services amazon-dynamodb database nosql

我正在考虑使用DynamoDB来生成用户Feed。 我将使用PostId(Range)存储UserId(Hash)。但我需要在数据库中保留最后3000个帖子。所以我正在考虑有一个后台任务来清理表格。 这样做有道理吗?我不确定这种类型的范围查询是否能够合理地快速运行,因为我有大约25万个用户记录。

请建议可能有效的任何其他选项(redis中的扇出除外)。

1 个答案:

答案 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操作一样多的删除操作。

来源: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GuidelinesForTables.html#GuidelinesForTables.TimeSeriesDataAccessPatterns

基于其他评论的更新答案:

"因此用户ID将成为我的哈希密钥。我需要的是清理程序......所以显然基于日期,单独的表方法将不会起作用,因为数据不是按时间帧而是按计数过滤的。在其他作品中,我需要为每个用户提供x个最近的记录。为了使它保持超过x的数量,我需要进行清理过程。"

在这种情况下,您几乎可以将Hash Key定义为UserId,将PostId定义为Range Key

如果每个用户最多可以有10个帖子,则Range Key最大值将为10.当您达到最大数量并且用户添加新帖子时,您将从1开始自动替换最旧的帖子来自该用户(有关详细信息,请参阅DynamoDB PutItem操作)。最后,您只是为每个用户创建一个循环的帖子列表。

通过这样做,你实际上是在添加新帖子并通过一次写操作立即执行清理过程。

您可能需要创建一个支持表,其中包含每个PostId发布的最后一个User。如果您选择仅将哈希键定义为UserId,则可以使用GetItem操作(非常便宜且快速)查找特定用户的最后一个PostId。该表的模式可以简单如下:

UserIdHash 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