【问题标题】:Cassandra Query Performance: Using IN clause for one portion of the composite partition keyCassandra 查询性能:对复合分区键的一部分使用 IN 子句
【发布时间】:2019-08-31 10:59:39
【问题描述】:

我目前在 Cassandra 中设置了一个表,该表具有文本、小数或日期类型列,其中 复合分区键 为 business_date 和 account_number。对于此表的查询,我需要能够支持对给定日期的单个帐户或帐户列表的查找。

例子:

select x,y,z from my_table where business_date = '2019-04-10' and account_number IN ('AAA', 'BBB', 'CCC')
//Note: Both partition keys are provided for this query

我一直在努力解决与访问这些数据相关的性能问题,因为我注意到我在尝试理解/解释时遇到困难的延迟模式。

在许多情况下,客户端应用程序可以在短时间内总共运行 3 次完全相同的查询。对于这些场景,我看到三分之二的请求的响应时间非常糟糕(800 毫秒),其中一个请求的响应时间非常快(50 毫秒)。起初我认为这是由于键或行缓存,但是,我不太确定,因为我相信如果这是真的,那么三个请求中的第三个请求应该总是最快的,但事实并非如此.

我认为我面临的第二个问题是实际的数据模型本身。尽管查询是在提供所有分区键的情况下提交的,但由于它是一个 IN 子句,因此结果将是单独的分区,并且可以分布在整个集群中,因此这将是一个糟糕的访问模式。但是,即使运行单个帐户查询,我也会看到这些延迟问题。此外,我发现 15 到 20 个帐户的查询表现非常好(低于 50 毫秒),所以我不确定数据模型是否真的存在问题。

集群设置:

  • 数据中心:2 个
  • 每个数据中心的节点数:3
  • 键空间复制:local_dc = 2,remote_dc = 2

Java 驱动程序集:

  • 负载平衡:DCAware 与 LatencyAware
  • 协议:v3
  • 查询仍设置为使用“IN”子句而不是异步单个查询
  • Read_consistency:LOCAL_ONE

在真正确定此问题的根本原因方面,是否有人对我应该关注什么有任何想法/线索?

【问题讨论】:

标签: cassandra query-optimization datastax-java-driver


【解决方案1】:

在分区键上使用IN 总是一个坏主意,即使对于复合分区键也是如此。分区键的值定义了数据在集群中的位置,不同的分区键值很可能会将数据放到不同的服务器上。在这种情况下,协调节点(接收到查询)将需要联系持有数据的节点,等待这些节点交付结果,然后再将结果发回给您。

如果您需要查询多个分区键,那么异步发出单个查询并在客户端收集结果会更快。

另外,请注意 TokenAware 策略在您使用 PreparedStatement 时效果最好 - 在这种情况下,驱动程序能够提取分区键的值,并找到哪个服务器为其保存数据。

【讨论】:

  • 谢谢@alex-ott。如果 IN 子句有问题,您是否知道如何解释以下内容:“但是,即使在运行单个帐户查询时,我也会看到这些延迟问题。此外,我看到带有 15 - 20 个帐户的查询执行得非常好(不到 50 毫秒),所以我不确定数据模型是否真的存在问题。”
  • 在某些分区上查询慢可能是由几个原因造成的:给定分区中有很多墓碑,分区很大,SSTables太多等。你可以在给定的表上执行nodetool tablestats看看什么是最大的分区,在最后一次请求中读取了多少个墓碑,等等。nodetool tablehistograms 对于获取高百分比的统计信息也很有用
猜你喜欢
  • 1970-01-01
  • 2016-11-23
  • 1970-01-01
  • 2016-03-22
  • 2015-02-01
  • 2016-01-14
  • 2019-07-17
  • 1970-01-01
相关资源
最近更新 更多