我正在开发DynamoDB上的论坛。
有一个表格帖子,其中包含一个帖子中的所有帖子。 我需要在帖子中有一个序列概念,即我需要知道哪个帖子先出现,后来出现哪个帖子。
我的服务将在分布式环境中运行。
我不确定使用Timestamp是决定序列的最佳解决方案,因为主机的时间可能略有不同,可能会超出我的毫秒/秒。
还有其他办法吗? 我可以让DynamoDB填充日期以使其保持一致吗? 或者我是否可以在分布式环境中使用序列生成器?
答案 0 :(得分:3)
您无法使用DynamoDB自动填充日期。您可以使用其他服务为您提供自动生成数字或use DynamoDB's原子增量来创建own UUID。 如果您的论坛非常成功(每秒需要大量数字),这可能会成为瓶颈。我认为你应该从时间戳开始,然后再增加你的id生成的复杂性(连接时间戳+ uuid或timstamp + atomiccounter)
同步服务器时钟(ntpd)始终是最佳做法
答案 1 :(得分:0)
陈的建议的另一个变体是在给定的论坛帖子中严格排序帖子,而不是在所有线程中全局排序。一种方法是使用一个带有ThreadId的Hash键的Reply表和一个ReplyId的范围键。 ReplyId将是一个从0开始的Number类型属性。每当有人回复时,您的应用程序在Reply表上为该线程上的最近一个回复执行Query(ScanIndexForward:false,Limit:1,ThreadId: )。要插入新回复,请使用查询中返回的回复,+ 1.然后使用PutItem,使用Conditional Write,以便如果其他人同时回复,则会出现错误返回,您的应用可以使用查询重新开始。
如果你想要最简单的初始解决方案,那么陈建议的时间戳+ uuid连接是最简单的方法。正如Chen所提到的,全局原子计数器项目将成为缩放瓶颈,并且根据您所描述的内容,您的应用程序不需要全局序列号。
答案 2 :(得分:0)
使用专用序列表。如果只有一个序列(例如PostId),那么表中将只有一行具有两个属性。
是的,管理另一个表需要额外的成本和精力,但这是迄今为止我所知道的最好的解决方案,而且还没有其他人提到它。
该表应具有一个key
属性作为主分区键,并具有一个数字value
属性,其初始值为1(或者您希望初始值为任何值)。
每次您想获取下一个可用密钥时,您都告诉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