从我所读到的到目前为止,Cassandra是使用客户端或协调器提供的时间戳来解决冲突的。如果Cassandra接收到对已经存在的单元格的写操作,它会选择时间戳更高的单元格。
在时钟偏差的情况下,当没有并发更新时,甚至当使用ALL
一致性级别时,仍然可能出现客户端已更新值并从所有服务器接收到ACK的情况。然而,实际值没有更新,因为提供的时间戳比该单元格的现有值旧(由于时钟偏差)。这种行为违反了AFAIK R+W〉N应该提供的因果一致性?
在我看来,使用逻辑时钟(lamport/vector clocks)来选择最新的值,只有当使用读取修复检测到并发更新时,才回退到使用实际时间戳(或客户端可以提供的其他策略)。这似乎是一个更好的解决方案,AFAIK这或多或少是dynamo使用的方法,对吗?
因为我可能错过了什么,你能让我知道为什么Cassandra不使用这种方法吗?
2条答案
按热度按时间mrwjdhj31#
Cassandra是一个最终一致的系统,当它(在Facebook)被设计出来的时候,工程师们必须决定如何处理冲突。他们有几个选择:Last Update Win、具有用于冲突的代码处理程序、将冲突解决委托给客户端等。
我猜他们去与最后更新赢由于简单。它有几个边缘的情况下,但他们设计 cassandra 为他们的目的,这种方法是为他们工作。
您所讨论的方法是有效的-系统将所有冲突的值返回给客户,然后由客户决定如何处理。它确实会增加客户端代码的复杂性,这可能不是所需的属性。
根据注解编辑:为什么是挂钟而不是逻辑钟
逻辑时钟(向量)有助于检测并发更新,但它不会帮助实际决定如何解决冲突。例如,如果对同一个密钥有两个更新,向量会检测到它们,但没有办法决定使用哪一个。
由于Cassandra不会返回冲突的版本(根据设计),也不会合并它们,因此他们需要一种方法来决定使用哪个记录。他们决定使用“上次更新成功”策略。此策略的一个选项是使用挂钟来决定。
另外,Lamport时间戳将提供总订单,但它需要系统中完全不同的数据流。
f0ofjuux2#
根据CAP定理,在网络分区的情况下,强一致系统将有停机时间。我们知道,逻辑时钟是强一致的,所以在分区的情况下,它们将有停机时间。
实际上,当你实现一个逻辑时钟时,你使用的是一种基于仲裁的算法,这对于网络分区的一端来说是不可用的,因为网络分区的节点数量较少。因此,在分区过程中,在你的例子中,使用逻辑时钟,A或B将进行写操作,而另一个节点将无法访问逻辑时钟,从而无法为写操作提供服务。
Cassandra开发人员有三种选择:
1.使用逻辑时钟并在分区期间降低可用性。
1.使用挂钟,并运行到你所提出的问题。
1.让客户端选择1或2。让客户端传递一个足够大的整数,该整数可以在客户端用1或2生成。
Casandra选择了3,但也提供了服务器端默认值2,以简化不需要逻辑时钟的客户端。如何在客户端生成与时钟时间(以米利斯为单位)大小相同的整数逻辑时间是一个单独的(已解决的)问题。