【问题标题】:Cassandra count with limitCassandra 计数有限制
【发布时间】:2021-03-21 23:39:23
【问题描述】:

我需要确定 Cassandra 表中的记录数是否大于某个数字,例如 10000。

我仍然没有大型数据集,但在大规模,可能有数十亿条记录,我如何才能有效地实现这一目标?

可能有数十亿条记录,或者只有数千条。我只需要知道是多于还是少于 10K。

下面的这似乎不对,我认为对于大量记录它会失败或非常慢。

SELECT COUNT(*) FROM data WHERE sourceId = {id} AND timestamp {startDate};

我也可以这样做:

SELECT * FROM data WHERE sourceId = {id} AND timestamp {startDate} LIMIT 10000;

在内存中计数

我不能有新表用于计数,例如,当写入新记录时,增加计数器,该选项是不可接受的。

还有其他方法可以做到这一点吗?限制选择看起来很愚蠢,但似乎最可行。

sourceId 是分区键,时间戳是集群键。

Cassandra 版本是 3.11.4,如果有什么相关的,我在 Spring 工作。

【问题讨论】:

  • 表结构是什么?

标签: cassandra


【解决方案1】:

您可以将bucket_id引入分区键,因此主键将是((sourceId,bucket_id),timestamp)。 Bucketing 用于 cassandra 来约束属于单个分区的数据行,即分区将被分成更小的块。要计算所有行,请使用附加时间戳字段对每个分区(source_id、bucket_id)发出异步查询。 Bucket_id 可能是从时间戳派生的,因此可以定义需要访问哪个 bucket_id。

另一种解决方案:

  • 使用 cassandra 的计数器(但我读到它会影响性能,并且无法正确处理重复和推测查询)
  • 使用另一个数据库,例如具有原子计数器的 redis(但是如何同步 redis 和 cassandra?)
  • 预先计算值并在写入期间保存(例如保存到静态列中)
  • 别的东西

【讨论】:

    【解决方案2】:

    第一个查询:

    SELECT COUNT(*) FROM data WHERE sourceId = {id} 
       AND timestamp < {endDate} AND timestamp > {startDate};
    

    如果你有一个主键如下的表应该可以工作:(sourceId, timestamp, ...) - 在这种情况下,聚合操作是在单个分区内执行的,所以它不会涉及多个节点的命中等。它仍然可能超时如果您的磁盘非常慢,并且给定时间范围内的数据过多。

    如果你有另一个表结构,那么你需要使用像 Spark 这样的东西,它会从 Cassandra 读取数据,执行过滤和计数......

    【讨论】:

      猜你喜欢
      • 2013-06-30
      • 2016-07-03
      • 2014-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-03
      相关资源
      最近更新 更多