完全复制的Cassandra集群上非主键查询的性能

时间:2018-12-29 21:45:32

标签: cassandra replication eventual-consistency

我已经使用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_notID是唯一的):

create TABLE stackoverflow.TABLE (T_ID int PRIMARY KEY, T_notID int, T_Data text);

当我调度多个(例如一百个)并发Java线程向Cassandra节点提交以下两个JDBC查询时(重复一分钟),我发现(B)查询的性能下降了100倍:

  

(A)在表T_ID =?中选择T_Data

     

(B)在表T_notID =?中选择T_Data允许过滤

(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查询和非PK查询的行为不同。

换句话说,考虑到在这种情况下read consistencyONE的事实,并且每个节点都可以响应查询而无需与集群中的其他节点通信(无论主键定义如何),我希望从Cassandra到集中式SQL数据库都具有类似的行为。

有人可以向我解释为什么会发生这种情况和/或如何解决吗?

1 个答案:

答案 0 :(得分:5)

当您对分区键有条件时-Cassandra知道数据在磁盘上的位置,并且可以跳转到分区开始并顺序读取数据。但是,如果您对非分区有条件,那么您的查询将需要遍历所有数据并仅过滤出必要的部分-您没有任何索引可以使Cassandra找出数据的位置。

如果您需要经常在T_notID上运行查询,则可以创建实例化视图或二级索引(但是您需要了解它们的局限性)。

DataStax的very good blog post关于允许过滤及其使用位置。