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

标签 cassandra replication eventual-consistency

我已经使用 Docker 容器在一台计算机上设置了一个完全复制的 3 节点 Cassandra 集群,状态如下:

数据中心:dc_n1
================
状态地址加载 token 拥有 Host_ID 机架
UN 172.18.0.3 83.98 MiB 256 100.0% 5bfrack_n1

数据中心:dc_n2
================
状态地址加载 token 拥有 Host_ID 机架
UN 172.18.0.6 83.52 MiB 256 100.0% 0518rack_n2

数据中心:dc_n3
================
状态地址加载 token 拥有 Host_ID 机架
UN 172.18.0.2 83.52 MiB 256 100.0% ca95rack_n3

现在考虑以下键空间:

使用复制 = {'class': 'NetworkTopologyStrategy', 'dc_n1':1,'dc_n2':1,'dc_n3':1}; 创建 KEYSPACE stackoverflow;

表定义为(假设 T_notID 是唯一的):

创建表 stackoverflow.TABLE (T_ID int PRIMARY KEY, T_notID int, T_Data text);

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

(A) SELECT T_Data FROM TABLE WHERE T_ID = ?

(B) SELECT T_Data FROM TABLE WHERE T_notID = ? ALLOW FILTERING

(B) 查询还会引发许多 Cassandra 错误: com.datastax.driver.core.exceptions.ReadTimeoutException:一致性 ONE 读取查询期间 Cassandra 超时(等待修复不一致副本时超时):

我知道,一般来说,在查询中使用“允许过滤”是一种反模式,应极其小心地使用,但在上面的简化示例中,因为数据完全复制并且每个项目的一个副本驻留在每个节点上,我不明白为什么 PK 查询和非 PK 查询的行为不同。

换句话说,考虑到这种情况下的读取一致性ONE,并且每个节点都可以响应查询而无需与集群中的其他节点通信(无论主键定义),我预计 Cassandra 到集中式 SQL 数据库会有类似的行为。

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

最佳答案

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

如果您需要经常在T_notID上运行查询,那么您可以创建物化 View 或二级索引(但您需要了解它们有哪些限制)。

DataStax 有 very good blog post关于允许过滤及其用途。

关于cassandra - 完全复制的 Cassandra 集群上非主键查询的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53973574/

相关文章:

node.js - 从 Node 连接到逻辑复制/流式传输还是去?

algorithm - 是否有任何通用算法可以在分布式系统中实现最终一致性?

google-app-engine - 游标是否处理最终一致性?

transactions - 如何处理跨有界上下文的长时间运行的流程/传奇用例

replication - Citus 分片、复制和复制

Cassandra 超时 cqlsh 查询大量数据

nosql - 从理论上理解 Cassandra 中的最终一致性

cassandra - 为什么两个 Cassandra 节点都拥有 100.0%?

file - 如何在 Cassandra 中存储小文件?

MySQL 复制错误 (1062)