Cassandra cql select 查询总是抛出读取超时异常

Cassandra cql select query throws read time out exception always

当我尝试执行以下查询时,我总是得到 QueryTimeOutException,

Exception is,
    com.datastax.driver.core.exceptions.ReadTimeoutException: Cassandra timeout during read query at consistency QUORUM (2 responses were required but only 0 replica responded)

Query is,
    SELECT * FROM my_test.my_table WHERE key_1 = 101 ORDER BY key_2 ASC LIMIT 25;

我正在使用具有 3 个节点的 cassandra 版本 2.1.0,具有 3 个复制的单个 DC,cassandra.yaml 具有所有默认值并且我有以下键空间和 table 作为架构,

CREATE KEYSPACE my_test
  WITH REPLICATION = { 
    'class' : 'SimpleStrategy', 
    'replication_factor' : 3
};

CREATE TABLE my_test.my_table (
    key_1 bigint,
    key_2 bigint,
    key_3 text,
    key_4 text,
    key_5 text,
    key_6 text,
    key_7 text,
    key_8 text,
    key_9 text,
    key_10 text,
    key_11 timestamp,
    PRIMARY KEY (key_1, key_2)
);

目前 table 有大约 39000 条记录,但最初有 50000 条记录,11000 条记录已因某些业务逻辑被删除。

解决方案之一to avoid such exception is to increase query read time out,但是我的架构和查询是more direct why should I increase my read time out? 因为在我的查询中我已经给出了分区键(key_1)所以它应该准确地到达目的地,之后我指定了分区键的起始范围, 所以它应该以 2 秒的最长时间检索,但事实并非如此。但是下面的查询工作正常并且检索结果不到 1 秒 (Difference is, ASC is not working and DESC is working)

SELECT * FROM my_test.my_table WHERE key_1 = 101 ORDER BY key_2 DESC LIMIT 25;

再次根据架构,集群键默认顺序是 ASC,因此根据 cassandra 文档,检索 ASC 中的数据应该比 DESC 顺序更快。 但我的情况正好相反。


又是一些线索,下面是通过CQLSH试过的查询。

以下查询正在运行,检索结果不到 1 秒

SELECT * FROM my_test.my_table WHERE key_1 = 101 AND key_2 > 1 AND key_2 < 132645 LIMIT 1;

但是,以下查询不工作并抛出超时异常,

SELECT * FROM my_test.my_table WHERE key_1 = 101 AND key_2 > 1 AND key_2 < 132646 LIMIT 1;

但是,以下查询有效,检索结果不到 1 秒

SELECT * FROM my_test.my_table WHERE key_1 = 101 AND key_2 = 132644;
SELECT * FROM my_test.my_table WHERE key_1 = 101 AND key_2 = 132645;
SELECT * FROM my_test.my_table WHERE key_1 = 101 AND key_2 = 132646;
SELECT * FROM my_test.my_table WHERE key_1 = 101 AND key_2 = 132647;

奇怪的行为,我们将不胜感激。

For each key_1 there will be around 1000000 key_2.

这就是当您采用每个分区 20 亿个单元格限制并尝试使用所有单元格时发生的情况。我知道我之前在这里回答过很多帖子,承认每个分区有 20 亿个单元格的硬限制,你的(非常)宽的行将变得笨拙并且可能超时 long 在那之前。这就是我相信你看到的。

此处的解决方案是一种称为 "bucketing." 的技术,基本上,您必须找到一个额外的键来对数据进行分区。太多的 CQL 行被写入同一个数据分区,分桶将有助于将分区与集群键的比率恢复到正常水平。

进行分桶的合乎逻辑的方法是使用时间元素。我看到你的最后一个密钥是时间戳。我不知道每个 key_1 一天有多少行,但假设您每个月只有几千行。在这种情况下,我会创建一个额外的分区键 month_bucket:

CREATE TABLE my_test.my_table (
    key_1 bigint,
    key_2 bigint,
    ...
    key_11 timestamp,
    month_bucket text,
    PRIMARY KEY ((key_1,month_bucket) key_2)
);

这将允许您支持这样的查询:

SELECT * FROM my_test.my_table 
WHERE key_1 = 101 AND month_bucket = '201603'
  AND key_2 > 1 AND key_2 < 132646 LIMIT 1;

同样,按月分桶只是一个例子。但基本上,您需要找到一个额外的列来对数据进行分区。

问题已解决 after restarting all the 3 cassandra servers。我不知道到底是什么造成了麻烦.. 因为它在生产服务器中无法获得确切的根本原因。