我使用docker容器在一台机器上设置了一个完全复制的3节点cassandra群集,状态如下:
Datacenter: dc_n1 =================
Status Address Load Tokens Owns Host_ID Rack UN 172.18.0.3 83.98 MiB 256 100.0% 5bf rack_n1
Datacenter: dc_n2 =================
Status Address Load Tokens Owns Host_ID Rack UN 172.18.0.6 83.52 MiB 256 100.0% 0518 rack_n2
Datacenter: dc_n3 =================
Status Address Load Tokens Owns Host_ID Rack UN 172.18.0.2 83.52 MiB 256 100.0% ca95 rack_n3
现在考虑以下键空间: create KEYSPACE stackoverflow WITH replication = {'class': 'NetworkTopologyStrategy', 'dc_n1':1,'dc_n2':1,'dc_n3':1};
表定义为(假设t\u notid是唯一的): create TABLE stackoverflow.TABLE (T_ID int PRIMARY KEY, T_notID int, T_Data text);
当我向cassandra节点发送大量(比如说100个)并发java线程提交以下两个jdbc查询(重复,一分钟)时,我看到(b)查询的性能下降了100倍:
(a) 从t\u id=?
(b) 从表中选择t\u data,其中t\u notid=?允许筛选
(b) 查询也会引发许多cassandra错误: com.datastax.driver.core.exceptions.ReadTimeoutException: Cassandra timeout during read query at consistency ONE (timeout while waiting for repair of inconsistent replica)
:
我知道,一般来说,在查询中使用“允许过滤”是一种反模式,应该非常小心地使用,但是在上面的简化示例中,由于数据是完全复制,并且每个节点上都有一个项目的副本,我不明白为什么pk查询和nonpk查询的行为不同。
换句话说,考虑到 read consistency
在这种情况下 ONE
而且每个节点都可以响应查询,而无需与集群中的其他节点进行通信(无论主键定义如何),我希望cassandra对集中式sql数据库有类似的行为。
有人能给我解释一下为什么会发生这种情况和/或我如何解决它吗?
1条答案
按热度按时间qq24tv8q1#
当您对分区键有条件时—cassandra知道数据在磁盘上的位置,并且可以跳到分区的开头并按顺序读取数据。但如果您有非分区的条件,那么您的查询将需要遍历所有数据并只过滤出必要的部分—您没有任何索引可以让cassandra找出数据所在的位置。
如果需要在
T_notID
通常,您可以创建物化视图或辅助索引(但您需要了解它们有哪些限制)。datastax有一篇非常好的关于允许过滤以及在哪里可以使用它的博客文章。