【问题标题】:DynamoDB: Have sequencing within ItemsDynamoDB:在项目中进行排序
【发布时间】:2014-09-12 21:55:36
【问题描述】:

我正在开发有关 DynamoDB 的论坛。

有一个表帖子,其中包含一个线程中的所有帖子。 我需要在帖子中有一个顺序的概念,即我需要知道哪个帖子先出现,哪个帖子后出现。

我的服务将在分布式环境中运行。

我不确定使用时间戳是否是确定序列的最佳解决方案,因为主机的时间可能略有不同,并且可能超出我的毫秒/秒。

还有其他方法可以做到这一点吗? 我可以让 DynamoDB 填充日期以使其保持一致吗? 或者有没有可以在分布式环境中使用的序列生成器?

【问题讨论】:

    标签: sequence distributed-computing amazon-dynamodb


    【解决方案1】:

    您不能使用 DynamoDB 自动填充日期。您可以使用其他服务为您提供自动生成数字或use DynamoDB's 原子增量来创建您的own UUID。 如果您的论坛非常成功(每秒需要大量数字),这可能会成为瓶颈。我认为您应该从时间戳开始,然后再为您的 id 生成增加复杂性(连接时间戳+uuid 或 timstamp+atomiccounter)

    同步您的服务器时钟 (ntpd) 始终是最佳实践

    【讨论】:

      【解决方案2】:

      使用专用序列表。如果您只有一个序列(例如 PostId),那么表中将只有一行具有两个属性。

      是的,管理另一个表需要额外的成本和精力,但这是迄今为止我所知道的最好的解决方案,还没有看到其他人提到它。

      该表应该有一个 key 属性作为主分区键,以及一个初始值为 1 的数字 value 属性(或任何您想要的初始值)。

      每次您想要获取下一个可用密钥时,您都告诉 DynamoDB 这样做:

      • 将value 其中key = PostId 递增1,并在递增之前返回值。

      请注意,这是一个单一的原子操作。 DynamoDB 处理自动递增,因此不存在并发问题。

      在代码中,实现这一点的方法不止一种。这是一个例子:

      Map<String,AttributeValue> key = new HashMap<>();
      key.put("key", new AttributeValue("PostId"));
      
      Map<String, AttributeValueUpdate> item = new HashMap<String, AttributeValueUpdate>();
      item.put("value",
                  new AttributeValueUpdate()
                      .withAction(AttributeAction.ADD)
                      .withValue(1));
      
      UpdateItemRequest request = new UpdateItemRequest("Sequences", key, item).withReturnValues(ReturnValue.ALL_OLD);
      UpdateItemResult result = dynamoDBClient.updateItem(request);
      Integer postId = Integer.parseInt(result.getAttributes().get("value").getN()); // <- this is the sequential ID you want to set to your post
      

      【讨论】:

      【解决方案3】:

      Chen 建议的另一个变体是在给定的论坛主题中对帖子进行严格排序,而不是在所有主题中全局排序。一种方法是创建一个Reply 表,其中Hash 键为ThreadId,范围键为ReplyId。 ReplyId 将是一个从 0 开始的数字类型属性。每次有人回复时,您的应用程序都会在回复表上为该线程上的一个最新回复执行Query(ScanIndexForward:false,Limit:1,ThreadId:)。要插入新回复,请使用查询中返回的回复 ID + 1。然后使用 PutItem,使用 Conditional Write,这样如果其他人同时回复,则会返回错误,并且您的应用可以通过查询重新开始。

      如果您想要最简单的初始解决方案,那么 Chen 建议的时间戳+uuid 连接是最简单的方法。正如 Chen 所提到的,全局原子计数器项将成为扩展瓶颈,并且根据您的描述,您的应用不需要全局序列号。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多