Java 奇怪的Cassandra ReadTimeoutException,取决于正在查询的客户端
我有一个由三个Cassandra节点组成的集群,具有或多或少的默认配置。最重要的是,我有一个web层,它由两个用于负载平衡的节点组成,两个web节点始终查询Cassandra。一段时间后,随着存储在Cassandra中的数据变得越来越重要,一个且只有一个web节点开始在特定查询上获取Java 奇怪的Cassandra ReadTimeoutException,取决于正在查询的客户端,java,cassandra,cassandra-2.0,Java,Cassandra,Cassandra 2.0,我有一个由三个Cassandra节点组成的集群,具有或多或少的默认配置。最重要的是,我有一个web层,它由两个用于负载平衡的节点组成,两个web节点始终查询Cassandra。一段时间后,随着存储在Cassandra中的数据变得越来越重要,一个且只有一个web节点开始在特定查询上获取ReadTimeoutException。web节点在各个方面都是相同的 查询非常简单(?是日期的占位符,通常在当前时刻前几分钟): 使用此查询创建表: CREATE TABLE table ( user_i
ReadTimeoutException
。web节点在各个方面都是相同的
查询非常简单(?
是日期的占位符,通常在当前时刻前几分钟):
使用此查询创建表:
CREATE TABLE table (
user_id varchar,
article_id varchar,
time timestamp,
PRIMARY KEY (user_id, time));
CREATE INDEX articles_idx ON table(article_id);
当超时时,客户端会等待10秒多一点,这并不奇怪,对于大多数连接和读取,都是在cassandra.yaml
中配置的超时
有几件事让我困惑不解:
- 查询仅在其中一个web节点执行时超时—其中一个节点始终失败,另一个节点始终成功李>
- 当我从
运行查询时,它会立即返回(尽管从那里运行查询时,它似乎只命中一个节点)cqlsh
- 发出的其他查询需要2-3分钟(比10秒超时时间长得多),但根本不会超时
cqlsh
中跟踪查询没有提供太多的洞察力。我不想改变卡桑德拉的超时,因为这是生产系统,我想先用尽非侵入性选项。Cassandra节点都有大量堆,它们的堆远没有满,GC时间似乎很正常
任何想法/指导都将不胜感激,我完全没有想法。Cassandra版本是2.0.2,使用
com.datasax.Cassandra:Cassandra驱动核心:2.0.2
Java客户端 我注意到了几件事:
time
作为集群键时,它并没有真正帮助您,因为您的查询不受分区键(user\u id
)的限制。Cassandra仅通过在分区内聚集键来排序。因此,现在您的查询正在回调满足WHERE子句的第一行,该行由user\u id
的散列标记值排序。如果您确实有数千万行,那么我希望此查询每次都能从相同的用户id
(或相同的select少数)中提取数据文章id
的基数是多少?记住,二级索引在“中间路线”基数上效果最好。高(唯一)和低(布尔)都不好ONE
,看看是否有帮助创建表tablebydaybucket(
用户id varchar,
第_idvarchar条,
时间戳,
day_bucket varchar,
主键(日期、时间)
按时间顺序进行聚类(时间描述)代码>
SELECT * FROM tablebydaybucket
WHERE day_bucket='20150519' AND time > '2015-05-19 15:38:49-0500' LIMIT 1;
这将按
day\u bucket
对数据进行分区,并按time
对数据进行聚类。这样,您就不需要允许筛选或二级索引。此外,您的查询保证只命中一个节点,而且Cassandra不必将所有行向后拉,并在事后应用WHERE子句。按降序在time
上进行聚类有助于更快地返回最近的行。此表中有多少行?在cqlsh中设置不同的一致性级别,然后重试again@BryceAtNetwork23:非常有洞察力,谢谢!该查询来自应用程序运行状况检查—我们希望数据流是连续的,如果没有新行,则说明有问题(因此,只接收一个用户的记录并不成问题)。实际的应用程序代码只根据使用的id进行选择。在任何情况下,似乎都无法解释为什么从一个框执行查询时会持续失败,而从另一个框执行查询时会持续成功。
SELECT * FROM tablebydaybucket
WHERE day_bucket='20150519' AND time > '2015-05-19 15:38:49-0500' LIMIT 1;