在Dynamo中写下冲突

时间:2017-06-02 11:13:59

标签: amazon-dynamodb distributed key-value distributed-system

成像有两个客户端client1和client2,两者都写相同的密钥。该密钥有三个副本名为A,B,C。第一个接收client1的请求,然后是client2',而B接收client2的请求,然后是client1' s。现在A和B必须彼此不一致,即使使用矢量时钟也无法解决冲突。我对吗?

如果是这样,似乎很容易在发电机中发生写冲突。为什么有这么多基于发电机设计的开源项目?

2 个答案:

答案 0 :(得分:0)

不能谈论HBase,但我可以谈论Cassandra,它受到Dynamo的启发。

如果在Cassandra中发生这种情况,那么最新的关键胜利。

Cassandra使用协调器节点(可以是任何节点),它们接收客户端请求并将它们重新发送到所有副本节点。这意味着每个请求都有自己的时间戳。

想象一下,Client2有最近的请求,在Client1之后几毫秒。

  • 副本A接收保存的Client1,然后保存Client2,Client2保存在Client1上,因为Client2是该密钥的最新信息。

  • 副本B接收已保存的Client2,然后接收Client1,因为它具有较旧的时间戳而被拒绝。

副本A和B都有Client2,这是最新的信息,因此是一致的。

答案 1 :(得分:0)

如果您使用的是Dynamo,并且担心比赛条件(如果您使用的是lambda,则应该如此)

如果条件失败,则可以检查putItem或updateItem上的条件

例如在getItem期间,时间戳为12345,添加条件,时间戳必须等于12345,但是另一个进程对其进行了更新,将时间戳更改为12346,您的put / update现在应该失败,例如在Java中,您可以捕获ConditionalCheckFailedException,可以执行另一个get项,在顶部应用您的更改,然后重新提交放置/更新


要防止新项目替换现有项目,请使用一个条件表达式,该条件表达式包含attribute_not_exists函数,该属性的名称用作表的分区键。由于每个记录都必须包含该属性,因此只有不存在匹配项时,attribute_not_exists函数才会成功。

有关PutItem的更多信息,请参阅Amazon DynamoDB开发人员指南中的使用项目。

参数: putItemRequest-表示PutItem操作的输入。 返回值: 服务返回的PutItem操作的结果。 抛出: ConditionalCheckFailedException-无法评估操作中指定的条件。

https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/AmazonDynamoDB.html#putItem-com.amazonaws.services.dynamodbv2.model.PutItemRequest-