Cassandra并发写道

时间:2017-06-14 02:45:07

标签: cassandra eventual-consistency nosql

当并发写入发生时,Cassandra如何保证最终的一致性?

例如,客户端A写入tableA.rowA.colA,同时客户端B写入tableA.rowA.colA。

协调器节点将请求分发给副本节点,例如NodeA NodeB和NodeC。

在NodeA上,ClientA请求首先到达。 在NodeB上,ClientB请求首先到达。 那么,它会永远不一致吗?

2 个答案:

答案 0 :(得分:5)

Cassandra遵循“最后写赢”政策。使用的时间戳可以手动设置,但默认情况下由请求者see Datastax Java Driver docs设置为客户端。写入的顺序无关紧要。如果写入A具有比写入B更早的时间戳,那么它将始终被写入B覆盖。唯一不明确的情况是时间戳完全匹配。在这种情况下,更大值获胜。

最终一致的部分是:

  • 假设A的时间戳早于B
  • 如果A到达副本1并且B到达副本2,则正确的状态是B
  • 副本1将响应A,直到它从副本2
  • 收到有关B的信息
  • 复制B时,副本1也会响应B.

大多数用例涉及不在Cassandra中存储状态,因此不会出现这些问题。

答案 1 :(得分:1)

每次写入(插入/更新/删除)到cassandra,也会插入与每列关联的时间戳。当您执行读取查询时,时间戳用于在单个列或集合元素中选择“获胜”更新

如果我使用相同的时间戳进行真正的并发写怎么办?在不太可能的情况下,你最终会得到两个匹配微秒的时间戳,你最终可能会得到一个糟糕的版本,但Cassandra通过比较字节值确保关系始终被打破

因此,对于您的案例“在NodeA上,ClientA请求首先到达。在NodeB上,ClientB请求首先到达”

  • 如果ClientA请求时间戳较旧,则ClientA将获胜

  • 如果ClientB请求时间戳较旧,则ClientB将获胜。

  • 如果ClientA和ClientB都具有相同的时间戳,则通过按字节顺序比较值来选择获胜者,以便返回的值是确定性的