Cassandra - 使计数器更新和正常更新原子

时间:2017-05-14 06:57:31

标签: java cassandra counter

我正在经历这个Instagram engineering article,他们提到了非正规化计数器,我引用

  

为了减少每个操作所需的资源,我们对帖子上的喜欢的计数器进行了非规范化。每当有新的类似物进入时,数据库中的计数就会增加。因此,每次读取计数都只是一个简单的“选择”,效率会更高。

     

还有一个额外的好处是在同一个非规范化计数器   存储liker的帖子的数据库。这两个更新都可以   包含在一个事务中,使更新成为原子和一致的   每时每刻。而在更改之前,缓存中的计数器可能是   与由于超时而存储在数据库中的内容不一致,   重试等。

我尝试更新计数器表和一个普通表,其中有一个用户喜欢批量使用该帖子,

BEGIN BATCH 
  UPDATE postlike_counter_counter
    set likecount = likecount+1 
    where postid = c77b9e44-379b-11e7-93dc-dd4982fae088;
  INSERT INTO postlikes (postid, likedtime, likedby) values(c77b9e44-379b-11e7-93dc-dd4982fae088, unixTimestampOf(now()), 
    {"firstname": 'fname', "lastname": 'lname', "profileimgurl":'img/pic'});
APPLY BATCH;

我看到错误, 计数器突变只允许在COUNTER批次中 如果我把它作为一个计数器批次,我得到, 在COUNTER批次中只允许计数器突变

有什么方法可以让我的工作吗?如果没有,那么这篇文章在撰写上述引用行时究竟是什么意思?

2 个答案:

答案 0 :(得分:2)

Ashraful Islam回答了为什么Cassandra不允许在一个批次中混合反查询和非反查询的问题。但是你引用的背景并没有发生在cassandra世界Instagram engineering article (De-normalizing Counters)试图在PgQ世界中进行解释(实际上可能的地方,它们不是计数器数据类型,而是维护为计数器类型)

答案 1 :(得分:0)

计数器更新和正常更新无法在同一批次中使用。

  

计数器批次不能在DML语句中包含非计数器列,就像非计数器批处理不能包含计数器列一样。计数器批处理语句无法提供自定义时间戳。

您必须使用单独的批次。

首先,您可以应用计数器批次,如果成功,则应用非计数器批次。如果非计数器批次未能切换计数器语句的符号(set a = a + 1 to a = a - 1或反之亦然)并应用批次。

在Java中,您可以通过wasApplied()方法

检查批处理是否成功
ResultSet resultSet = session.execute(batch);

if(resultSet.wasApplied()) {
    // Batch success
}

来源:https://docs.datastax.com/en/cql/3.3/cql/cql_reference/cqlBatch.html