我们正在使用rest api在cassandra中执行查询,而我们的查询中的一个提取计数正在为我们创建问题。
我们已经构建了cassandra集群,最近,我们已经完成备份和恢复,并将所有数据复制到新集群。 我们已经对表进行了nodetool刷新,并且也进行了nodetool修复。
但是,我们的一些API调用失败并返回不一致的结果。
1)count查询中包含分区键。没有看到任何读取超时或来自api调用的任何错误。
2)这就是我们创建会话代码的样子。
val poolingOptions = new PoolingOptions
poolingOptions
.setCoreConnectionsPerHost(HostDistance.LOCAL, 4)
.setMaxConnectionsPerHost(HostDistance.LOCAL, 10)
.setCoreConnectionsPerHost(HostDistance.REMOTE, 4)
.setMaxConnectionsPerHost( HostDistance.REMOTE, 10)
val builtCluster = clusterBuilder.withCredentials(username, password)
.withPoolingOptions(poolingOptions)
.build()
val cassandraSession = builtCluster.get.connect()
val preparedStatement = cassandraSession.prepare(statement).setConsistencyLevel(ConsistencyLevel.QUORUM)
cassandraSession.execute(preparedStatement.bind(args :_*))
群集配置:
6台机器:3粒种子
cassandra永远不会在任何机器上停机
我们正在使用apache cassandra 3.9版本
在3.1.1版本中使用cassandra-driver-core artifact。
3)nodetoop tpstats显示没有失败。
4)不要在cassandra的system.log中看到任何其他问题。我们只看到一些警告如下。
Maximum memory usage reached (512.000MiB), cannot allocate chunk of 1.000MiB
WARN [ScheduledTasks:1] 2017-03-14 14:58:37,141 QueryProcessor.java:103 - 88 prepared statements discarded in the last minute because cache limit reached (32 MB)
第一个api调用返回0,后面的api调用给出正确的值。
如果需要任何其他详细信息,请告诉我。
答案 0 :(得分:1)
不要使用count(*),请使用计数器
count(*)
非常低效。 Cassandra需要扫描所有行才能给你计算。如果你有大量的数据cassandra可以抛出超时异常。
使用计数器代替:
计数器是一个特殊列,用于存储以增量方式更改的数字。例如,您可以使用计数器列来计算查看页面的次数。
让我们定义一个表格:
CREATE TABLE counter_test (
pk int,
ctkey text,
cdkey date,
count counter,
PRIMARY KEY (pk, ctkey, cdkey)
);
增加计数器的值:
UPDATE counter_test SET count = count + 10 WHERE pk = 1 AND ctkey = 'hi' AND cdkey = '2017-03-16';
减少计数器的值:
UPDATE counter_test SET count = count - 5 WHERE pk = 1 AND ctkey = 'hi' AND cdkey = '2017-03-16';
选择计数器的值:
SELECT * FROM counter_test WHERE pk = 1 AND ctkey = 'hi' AND cdkey = '2017-03-16';
你会得到:
pk | ctkey | cdkey | count
----+-------+------------+-------
1 | hi | 2017-03-16 | 5
来源:https://docs.datastax.com/en/cql/3.1/cql/cql_using/use_counter_t.html