社交网络架构设计演变

DynamoDB 是一个 NoSQL 数据库,因此不允许您执行联接操作,也就是合并来自多个数据库的数据的操作。不熟悉 DynamoDB 的客户可能会不必要地将关系数据库管理系统 (RDBMS, Relational DataBase Management System) 的设计理念(例如为每个实体创建表)应用于 DynamoDB。DynamoDB 单表设计的目的是根据应用程序的访问模式,以预先联接的形式写入数据,然后无需额外计算即可立即使用数据。有关更多信息,请参阅 DynamoDB 中的单表与多表设计。

现在,我们来逐步了解一下如何改进架构设计以解决所有访问模式。

步骤 1:解决访问模式 1 ( getUserInfoByUserID )

要获取给定用户的信息,我们需要使用键条件 PK=<userID> 对基表执行 Query 操作。查询操作允许您对结果进行分页,这在用户有很多关注者时很有用。有关 Query 的更多信息,请参阅 DynamoDB 中的查询操作 。

在示例中,我们跟踪用户的两种类型的数据:他们的“count”和“info”。用户的“count”反映了他们有多少粉丝,他们关注了多少用户,以及他们创建了多少帖子。用户的“info”反映了他们的个人信息,例如他们的姓名。

我们看到这两种数据类型由以下两项表示。排序键 (SK) 中带有“count”的项目比带有“info”的项目更有可能发生改变。DynamoDB 会考虑更新前后的项目大小,所消耗的预置吞吐量将反映这些项目大小中较大的一个。因此,即使您只更新项目属性的子集, UpdateItem 仍会消耗全部的预置吞吐量(之前和之后项目大小中的较大者)。您可以通过单个 Query 操作获取项目,并使用 UpdateItem 对现有的数值属性进行加减。

步骤 6:解决访问模式 6 ( getLikeCountByPostID )

要获取给定帖子的点赞数,我们需要使用键条件 PK=<postID>#likecount 对基表执行 GetItem 操作。当拥有许多粉丝的某个用户(例如名人)创建帖子时,这种访问模式可能会导致节流问题,因为当单个分区的吞吐量超过每秒 1000 个 WCU 时,就会出现节流。这个问题不是 DynamoDB 造成的,只是正好出现在 DynamoDB 中,因为它位于软件堆栈的最后部分。

您应该评估一下是否有必要让所有用户同时查看点赞数,还是可以在一段时间内逐步显示。通常,帖子的点赞数不必立即获得 100% 准确的值。您可以通过在应用程序和 DynamoDB 之间放置队列,用于定期进行更新,以此来实施此策略。

步骤 7:解决访问模式 7 ( getTimelineByUserID )

要获取给定用户的时间线,我们需要使用键条件 PK=<userID>#timeline 对基表执行 Query 操作。我们来考虑一个场景,即用户的粉丝需要同步查看用户的帖子。每次用户发了一个帖子时,都会读取用户的粉丝名单,并将用户的 userID 和 postID 逐步输入其所有粉丝的时间线中。然后,当应用程序启动时,您可以通过 Query 操作读取时间线键,并对任何新项目使用 BatchGetItem 操作,将 userID 和 postID 的组合结果来填充时间线屏幕。您无法通过 API 调用来读取时间线,但是如果帖子经常会进行编辑,则这是一种更具成本效益的解决方案。

时间线是显示最近帖子的位置,所以我们需要一种方法来清理旧帖子。您可以使用 DynamoDB 的 TTL 功能来免费删除旧帖子,而无需使用 WCU。

在此架构设计中使用 NoSQL Workbench

若要进一步探索和编辑新项目,您可以将此最终架构导入到 NoSQL Workbench ,这是一款为 DynamoDB 提供数据建模、数据可视化和查询开发功能的可视化工具。请按照以下步骤开始使用:

下载 NoSQL Workbench。有关更多信息,请参阅 下载 NoSQL Workbench for DynamoDB 。

下载上面列出的 JSON 架构文件,该文件已经采用 NoSQL Workbench 模型格式。

将 JSON 架构文件导入到 NoSQL Workbench。有关更多信息,请参阅 导入现有数据模型 。