如何在Cassandra中删除后用计数器列重置记录?

时间:2016-11-10 10:09:21

标签: cassandra counter datastax-java-driver

我在使用com.datastax.driver.core包和类中的函数时创建了一个带有计数器列的表:

public void doStartingJob(){
   session.execute("CREATE KEYSPACE myks WITH replication "
            + "= {'class':'SimpleStrategy', 'replication_factor':1};");
   session.execute("CREATE TABLE myks.clients_count(ip_address text PRIMARY KEY,"
                                        + "request_count counter);");
}

在此之后我从CQLSH中删除了表条目,如:

jay@jayesh-380:~$ cqlsh
Connected to Test Cluster at 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 3.9 | CQL spec 3.4.2 | Native protocol v4]
Use HELP for help.

cqlsh:myks> DELETE FROM clients_count WHERE ip_address='127.0.0.1';

然后插入具有相同主键的行我使用以下语句(通过cqlsh):

UPDATE myks.clients_count SET request_count = 1 WHERE ip_address ='127.0.0.1';

不允许

InvalidRequest: Error from server: code=2200 [Invalid query] message="Cannot set the value of counter column request_count (counters can only be incremented/decremented, not set)"

但是,我希望记录的计数器列的值应设置为1 ,并使用相同的主键。 (功能要求)

如何做同样的事情?

1 个答案:

答案 0 :(得分:3)

计数器的使用有点奇怪,但你会习惯的。但最重要的是,计数器不能重用。删除特定主键的计数器值后,此计数器将永久丢失 。这是设计,我认为不会改变。

回到你的问题,你的第一个问题是最初的DELETE。不。

其次,如果主键的计数器值不存在,则默认情况下C *会将处理为零。在the documentation之后,要首次在计数器中加载数据,您必须发出:

 UPDATE mysecurity.clients_count SET request_count = request_count + 1 WHERE ip_address ='127.0.0.1';

SELECT将返回正确答案:1

再次提防删除!别!如果你这样做,任何后续查询:

 UPDATE mysecurity.clients_count SET request_count = request_count + 1 WHERE ip_address ='127.0.0.1';

NOT 会失败,但计数器会 NOT 更新。

需要注意的另一件事是C *不支持原子读取和更新(或更新并读取计数器列。这是你不能发布更新和在同一查询中获取计数器的新(或旧)值。您需要执行两个不同的查询,一个使用SELECT,另一个使用UPDATE,但是在多客户端环境中您获得的SELECT值无法反映UPDATE期间的计数器值。

如果你低估了这个,你的应用肯定会失败。