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
。我不知道到底是什么造成了麻烦.. 因为它在生产服务器中无法获得确切的根本原因。
当我尝试执行以下查询时,我总是得到 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
。我不知道到底是什么造成了麻烦.. 因为它在生产服务器中无法获得确切的根本原因。