【问题标题】:Real time complex queries on CassandraCassandra 上的实时复杂查询
【发布时间】:2015-08-20 08:22:22
【问题描述】:

我们正在寻找一种工具(最好是开源的),它可以帮助我们实时执行复杂的查询(高级过滤和连接,不需要完整的 SQL)。

假设所需的所有数据都适合内存,并且我们希望尽可能避免 map reduce 工具的开销。

更具体地说,我们需要加载单个表的n个分区,并通过聚集列将它们连接起来。

Variables Table:
Variable ID: Partition key
Person ID: Clustering key
Variable Value

Desired output columns:
Person ID, Variable 1 Value, Variable 2 Vale, ..., Variable N Value 

我们可以通过内存中的 load-filter-join 过程来实现它,但我们想知道是否有任何工具可以开箱即用地涵盖此用例并具有公平的性能。

我们测试过 Spark,但是 Spark C* 连接器的分区是基于主键的,所以每个变量 ID 会被加载到不同的 Spark 节点中,并且连接过程会非常慢(所有数据都会遍及 Spark 集群)。

有什么建议吗?已知工具?

【问题讨论】:

标签: cassandra


【解决方案1】:

我相信您有多种选择来执行此任务:

  • 重新考虑您的数据库架构,对其进行非规范化。如果您想通过 person_id 查询,var_id:person_id:value 行不是最好的表模式(而且它闻起来像entity-attribute-value db antipattern 真的很糟糕):

EAV 为开发人员提供了根据需要定义架构的灵活性,这在某些情况下很好。另一方面,它在定义不明确的查询的情况下表现很差,并且可以支持其他不良做法。换句话说,EAV 给了你足够的绳索让你上吊,在这个行业中,事情应该设计成最低程度的复杂性,因为在项目中取代你的人很可能是个白痴。

你可以使用多列的模式(cassandra 可以处理很多):

create table person_data (
  person_id int primary key,
  var1 text,
  var2 text,
  var3 text,
  var4 text,
  ....
);

如果您没有预定义的变量集,则可以使用 cql3 集合(如 map)以更灵活的方式存储数据。

  • 在 person_id 上创建二级索引(即使它已经是集群键)。您可以在不使用联接的情况下查询特定用户的所有数据,但存在一些问题:

    • 由于您的查询将访问多个分区,因此它需要的不是单个磁盘查找,而是一系列磁盘查找,因此您的查询延迟可能比您预期的要高。
    • 二级索引不是免费的:如果您将行插入到具有索引列的表中,C* 必须在后台执行更多工作。
  • 使用外部索引,例如 ElasticSearch/Solr,如果您计划处理大量不适合 cql3 的复杂查询。

【讨论】:

  • 感谢您的回答。我的使用模式不是获取一个人的所有变量,而是获取一个变量子组的所有人值。输入是变量列表,输出是人员列表及其每个变量的值。将变量用作分区键对我来说似乎是合理的,但也许我在这里遗漏了一些重要的点。
  • 每列变量的解决方案被丢弃,因为变量非常动态,并且使用应用程序代码动态创建的无限数量的列似乎是一个糟糕的设计。我们还测试了 Cassandra 集合,它们的性能确实很差(将变量存储在地图中),并且某些 CQL 功能无法使用集合。
猜你喜欢
  • 2011-02-10
  • 2017-08-15
  • 2015-07-16
  • 2018-10-03
  • 1970-01-01
  • 2021-11-30
  • 2023-03-20
  • 2015-12-16
相关资源
最近更新 更多