0

我对 DynamoDB 很陌生,正在尝试解决问题。我正在设计一个包含多个实体的表(实体和属性不是真实的,但我希望它们能让您了解问题):

  • 邮政
  • 评论

目标是在此表中存储要发布的帖子和 N 个最新评论。

假设 Post 实体具有属性:Title, Author, Text。PK:POST#<ID>和SK #POST#<ID>:。对于评论,我对作者、评论文本和提交日期感兴趣。所以属性是:Author, Text, SubmittedAt. PK:POST#<ID>和SK #COMMENT#<COMMENT_ID>:。我的物品看起来像这样:

{"PK": "POST#1", "SK": "#POST#1", "Title": "Some", "Author": "john@doe.com", "Text": "Post text 1"}
{"PK": "POST#1", "SK": "#COMMENT#1", "Author": "author1@comment.post" "Text": "Some text1", "SubmittedAt": "2020-09-01T22:43:00+00:00"}
{"PK": "POST#1", "SK": "#COMMENT#2", "Author": "author1@comment.post" "Text": "Some text2", "SubmittedAt": "2020-09-02T22:43:00+00:00"}
{"PK": "POST#1", "SK": "#COMMENT#3", "Author": "author2@comment.post" "Text": "Some text3", "SubmittedAt": "2020-09-03T22:43:00+00:00"}

正如您所想象的那样,帖子可能很热门并且经常被评论。我正在尝试尽可能快且尽可能便宜地更新此表。我需要在表格中存储每个帖子最多 5 条评论。

到目前为止,我有两个想法:

  1. Read before write:阅读评论,比较 SubmittedAt,获取最旧的,将其推出并写入新项目 --> 减慢“提交评论”操作(API 调用)
  2. 编写,使用 DynamoDB Stream + Lambda 进行后处理,这无论如何都需要阅读整个内容 --> 引入了另一段代码来维护以及流和 lambda 的成本。

实现这一目标的其他方法是什么?会推荐哪一个?

先感谢您!

4

1 回答 1

2

事务是处理此用例的另一种方式。

您可以对Post项目中的评论数进行计数,并且仅在该计数低于 5 时才插入新评论。DynamoDB 事务可以使用transact_write_items在单个操作中完成所有这些操作。例如:

dynamodbclient.transact_write_items(
  TransactItems: [
      { // insert a new Post item
        Put: {
          TableName: my_table,
          Item: {                  
            PK: "POST#1",
            SK: "COMMENT#1",
            Author: "author1@comment.post",
            Text: "some text 1",
            submittedAt: "2020-09-03T22:43:00+00:00"
          }
        }
      },
      { // conditionally Update the num_comments attribute 
        Update: {
          TableName: "my_table",
          Key: {
            PK: "POST#1",
            SK: "POST#1"
          },
          ConditionExpression: "num_comments < 5",
          UpdateExpression: "SET #num_comments = #num_comments + :incr",
          ExpressionAttributeNames: {
            "#num_comments": "num_comments"
          },
          ExpressionAttributeValues: {":incr": 1}
        }
      }
    ]
)

DynamoDB Transactions在单个请求中最多可支持 25 个操作。交易是“全有或全无”;要么所有操作都成功,要么都失败。在这个特定的事务中,您正在执行两个操作:

  1. 使用 Put 请求创建新的评论项目
  2. 仅当 num_comments 小于 5 时才num_comments增加Post 项目的计数器

如果num_comments小于 5,则事务将成功,您将插入评论并增加 Post.num_comments。否则,任何操作都不会发生。

请记住以下内容(来自文档):

为您的 DynamoDB 表启用事务无需额外费用。您只需为交易中的读取或写入付费。DynamoDB 对事务中的每个项目执行两个底层读取或写入:一个用于准备事务,另一个用于提交事务。两个底层读/写操作在您的 Amazon CloudWatch 指标中可见。

于 2020-09-01T21:57:44.487 回答