增加并获取计数器的值
Increment and get value of counter
有没有办法增加一个计数器,然后在一次调用中取回值?
或者是拨打 2 个电话的唯一方法?
这不是幻影限制,而是 Cassandra API 的限制,CQL 中没有任何东西允许您在同一个 API 调用中检索和更新值,并且有一个非常非常很好的理由。
当您更新计数器的值时,CQL 如下所示:
UPDATE keyspace.table SET counter = counter + 1 WHERE a = b;
然而,这掩盖了 Cassandra 执行看似简单的增量所必须经历的真正的分布式锁定复杂性。这是因为很难确保每个计数都在更新 latest
值,并且同一计数器的多个增量最终会得到相同的值。
因此您需要保证写入被足够多的副本确认,然后您才能执行安全读取,这听起来真的很容易。实际上,有一个增量 merge/compare-and-set 过程以单个计数器增量进行,更详细 here.
读取操作很简单:
SELECT * FROM keyspace.table WHERE a = b;
如果您认为这样做可以节省大量网络或复杂性,那么您可能不会这样做,除非 read/writes 的数量是巨大的。简而言之,这是一个快乐的想法,但我不会打扰。
for {
inc <- database.table.update.where(_.a = b).modify(_.counter increment 1).future()
value <- database.table.select(_.counter).where(_.a = b).one()
} yield value
有没有办法增加一个计数器,然后在一次调用中取回值?
或者是拨打 2 个电话的唯一方法?
这不是幻影限制,而是 Cassandra API 的限制,CQL 中没有任何东西允许您在同一个 API 调用中检索和更新值,并且有一个非常非常很好的理由。
当您更新计数器的值时,CQL 如下所示:
UPDATE keyspace.table SET counter = counter + 1 WHERE a = b;
然而,这掩盖了 Cassandra 执行看似简单的增量所必须经历的真正的分布式锁定复杂性。这是因为很难确保每个计数都在更新 latest
值,并且同一计数器的多个增量最终会得到相同的值。
因此您需要保证写入被足够多的副本确认,然后您才能执行安全读取,这听起来真的很容易。实际上,有一个增量 merge/compare-and-set 过程以单个计数器增量进行,更详细 here.
读取操作很简单:
SELECT * FROM keyspace.table WHERE a = b;
如果您认为这样做可以节省大量网络或复杂性,那么您可能不会这样做,除非 read/writes 的数量是巨大的。简而言之,这是一个快乐的想法,但我不会打扰。
for {
inc <- database.table.update.where(_.a = b).modify(_.counter increment 1).future()
value <- database.table.select(_.counter).where(_.a = b).one()
} yield value