2015-12-26 73 views
0

在我看来,如果重新尝试,使用IF会使声明失败。因此,该声明不是幂等的。例如,考虑到以下CQL,如果由于超时或系统问题而失败,并且我重试了它,那么它可能无法工作,因为另一个人可能在重试之间更新了版本。CQL3“IF”是否使我的更新不是幂等的?

UPDATE users 
SET name = 'foo', version = 4 
WHERE userid = 1 
IF version = 3 

Cassandra更新的最佳实践是使更新幂等,但IF操作符与此直接相反。我错过了什么吗?

回答

1

这个问题更关于线性化(排序)比我认为幂等性。此查询使用Paxos在应用更改之前尝试确定系统的状态。如果系统的状态是相同的,那么可以多次重试查询而不改变结果。这与大多数Cassandra写道的不同,这提供了一种弱的排序形式(并且代价昂贵)。通常,如果您试图记录系统状态(而不是历史记录或日志),则只应使用CAS操作

如果您可以提供帮助,请不要使用其中的许多查询,指南建议只有一小部分您的查询依赖于此行为。

2

如果您的应用程序是幂等的,那么通常您不需要使用昂贵的IF子句,因为您的所有客户端都将尝试设置相同的值。

例如,假设您的客户正在汇总某些值并将结果写入汇总表。每个客户端都会计算相同的总数并写入相同的值,因此多个客户端写入该客户端或写入该客户端的顺序并不重要,因为它将具有相同的值。

如果您实际所寻找的是互相排斥,例如保持银行平衡,那么可以使用IF子句。您可能会读取一行以获得当前余额,然后减去一些资金并仅在余额自您读取后没有改变时更新余额。如果另一个客户试图同时添加存款,那么它将失败,并且将不得不再次尝试。

但是,如果不互相排斥,另一种方法是将每个提款和存款作为单独的集群交易行编写,然后将余额计算为应用所有交易行的幂等结果。

您可以使用IF子句进行幂等写入,但似乎毫无意义。第一个执行写操作的客户端会成功,Cassandra会返回值“applied = True”。下一个尝试同样写入的客户端将返回“applied = False,version = 4”,表示该行已经更新到版本4,因此没有任何更改。

相关问题