我正在经历这个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批次中只允许计数器突变
有什么方法可以让我的工作吗?如果没有,那么这篇文章在撰写上述引用行时究竟是什么意思?
答案 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