以下情况对Cassandra来说可能是逻辑正确的,但对用户来说是困难的。
Cassandra一致性级别:全部写入,读取一个replication_factor:3
对于一条记录,行键:001,列:状态
1.客户端1,插入行键001的值,状态:真,时间戳11:00:05
1.客户端2切片查询,获取行键001的值True,@11:00:00
1.客户端2,更新行键001的值,状态:假,时间戳11:00:02
所以客户端的更新顺序是True to False,虽然更新请求来自不同的节点,但是顺序是逻辑有序的。
但结果是行键:001,列:状态,值:真的
那么为什么Cassandra如此依赖客户端本地时间呢?为什么不使用服务器本地时间来代替客户端本地时间呢?
因为我使用一致性级别write all,并且replication_factor:3,所以对于所有3个节点,更新顺序是正确的(True -〉False),它们可以给予正确的最终结果。
如果由于某种原因,它需要强烈依赖于操作的时间戳,那么查询操作也需要时间戳,那么客户端2将不会看到值True,这在“将来”发生。
因此,无论是使用服务器时间戳还是查询也需要时间戳(这意味着,第二步查询将看不到结果,因为数据是“未来”的),都将更加一致。
否则, cassandra 的一致性是如此之弱,甚至R + W〉N。
3条答案
按热度按时间zlhcx6iw1#
简单地说,CQL实际上默认使用服务器提供的时间戳。
作为一个更长的答案,我在http://www.datastax.com/dev/blog/why-cassandra-doesnt-need-vector-clocks上写了一篇关于时间戳在冲突解决中的作用的文章。
ldxq2e6h2#
CQL使用服务器端时间戳,但是遗留Thrift接口使用客户端时间戳。
请注意,您所描述的不是一致性问题,因为所有响应在写入后都将彼此一致。但这违反了因果关系。即使使用服务器端时间戳,您也可能在同时写入相同列时遇到问题。
以下是对其中一些问题的讨论:http://aphyr.com/posts/294-call-me-maybe-cassandra
chhkpiq43#
因为我也有同样的问题,我会把这个信息留在这里,即使它已经有10年的历史了:)使用服务器端时间戳是可能的。
时间戳可以由驱动程序客户端或协调请求的服务器端节点分配。默认情况下,所有最新版本的DataStax驱动程序都使用客户端生成的时间戳,用于Cassandra版本2.1和更高版本以及DSE版本4.7和更高版本。Cassandra和DSE的旧版本不支持客户端时间戳,因为它们是在CQL本地协议版本3中引入的。
默认情况下,客户端时间戳生成可从单个客户端的Angular 保持操作顺序的可预测性。通过单调增加客户端时间戳,驱动程序可确保所有操作都按照在该示例范围内执行的顺序写入。
如果没有客户端时间戳,客户端就可以随心所欲地使用协调节点分配的时间戳。协调节点根据其内部系统时钟分配时间戳。在分布式系统中,很难保持不同节点的系统时钟同步。即使节点使用NTP或其他时钟同步软件,每个节点也会受到数十毫秒到数秒的时钟漂移的影响。
来源:https://docs.datastax.com/en/dev-app-drivers/docs/queryTimestamps.html
因此,在服务器端生成的情况下,看起来如下所示:分配给不同节点的时间戳不能保证是全局唯一的。2在稳定的高写速率下,时间戳冲突是不可能的。