Cassandra cql select查询始终抛出读取超时异常

时间:2016-03-17 11:10:02

标签: cassandra cql datastax-java-driver cqlsh

当我尝试执行以下查询时,我总是收到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的Single DC,cassandra.yaml具有所有默认值,并且我将以下键空间和表作为模式,

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)
);

目前该表有大约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)所以它应该准确到达目的地,之后我指定了parition键的起始范围, 因此它应该以最大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;

奇怪的行为任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

  

对于每个key_1,将有大约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;

再一次,月份上的分期只是一个例子。但基本上,您需要找到一个额外的列来对数据进行分区。

答案 1 :(得分:1)

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