在Cassandra中读取更新计数器值的最佳方法是什么?让我们说从我的应用程序中我需要更新一个计数器,然后使用它的更新值。所以我有两个查询,第一个更新计数器,下一个读取它。据我所知,由于数据的复制,无法保证读取查询将获得更新的计数器。所以我可以看到有两种方法:
使用一致性级别ALL更新计数器,然后读取它。我不确定此操作的性能影响是什么?
在更新之前读取计数器值,然后更新它。然后将读取值增加1并使用它。现在我认为这种方法没有任何问题?
或者可能还有其他方法和其他一些我没有考虑的因素?
无论如何,我很乐意找出最佳做法是什么?
答案 0 :(得分:1)
据我所知,由于数据的复制,无法保证读取查询将获得更新的计数器。
问题更多的是关于计数器的分布式设计。请参阅以下时间表
初始计数器值= 0
如果客户A在 t2之前读回计数器值,它将看到counter = 5
如果客户A在 t2之后回读计数器值,它将看到counter = 8(+5 +3)
如果您在读回计数器值时,其他人已更新或不更新,那么您现在不能。使用轻量级事务(LWT)使计数器更新可线性化不是一个选项,因为计数器表不支持LWT。
也许您应该描述一下您的用例,以便我们能够设计出合适的方法。你想用柜台做什么?您希望创建什么类型的查询以读取您的计数器?
答案 1 :(得分:1)
正如@doanduyhai解释的那样,当并发客户端同时增加计数器时,两种方法都容易出错。 这是我们设计上的问题,我们使用一个计数器表作为其他表的键,因此我们需要唯一的ID。是的,我们知道我们可以使用UUID作为唯一ID,但是我们希望保持键的排序并易于在客户端读取。 我们的解决方案:
v1 =读取计数器A。
-增加计数器A。
v2 =再次读取计数器A。
如果v2 == v1 + 1,则该过程是单独的还是第一个,请使用计数器并忘记。
如果不是,则表明存在多个进程竞争的信号,因此:
随机睡眠(因此每个进程睡眠不同的时间,并且不会永远竞争),然后重试整个循环。