当我尝试执行以下查询时,我总是收到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;
奇怪的行为任何帮助将不胜感激。
答案 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
。我不知道到底是什么麻烦..因为它在生产服务器无法得到确切的根本原因。