成像有两个客户端client1和client2,两者都写相同的密钥。该密钥有三个副本名为A,B,C。第一个接收client1的请求,然后是client2',而B接收client2的请求,然后是client1' s。现在A和B必须彼此不一致,即使使用矢量时钟也无法解决冲突。我对吗?
如果是这样,似乎很容易在发电机中发生写冲突。为什么有这么多基于发电机设计的开源项目?
答案 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-无法评估操作中指定的条件。