【问题标题】:Cassandra time series data (right approach?)Cassandra 时间序列数据(正确的方法?)
【发布时间】:2016-01-25 15:45:59
【问题描述】:

我们有一个包含大量时间序列数据的表。可能我们必须在该表中每毫秒存储几个条目。为了满足这些要求,表格看起来像

CREATE TABLE statistic (
    name        text,
    id          uuid,
    start       timestamp,
    other_data  ...,

PRIMARY KEY (name, start, id)
) WITH CLUSTERING ORDER BY (start DESC);

如您所见,该表由两个聚类键组成,start 存储数据到达的时间,id 的目的是避免数据同时到达时被覆盖。

现在可以了,我们可以像这样进行范围查询

SELECT * FROM statistic WHERE name ='foo' AND start >= 1453730078182
     AND start <= 1453730078251;

但我们还需要能够在查询中添加额外的搜索参数,例如

SELECT * FROM statistic WHERE name = 'foo' 
    AND start >= 1453730078182 AND start <= 1453730078251 AND other_data = 'bar';

这当然行不通,因为other_data 不是主键的一部分。如果我们将它添加到主键,我们会得到以下错误

InvalidRequest: code=2200 [Invalid query] message="PRIMARY KEY 列 "other_data" 不能被限制(前面的列 "start" 受非 EQ 关系限制)"

没关系,这不是Cassandra 的工作方式(我认为)。

我们解决问题的方法是使用上述(第一个)范围查询选择所需的(时间序列)数据,然后在我们的 Java 应用程序中过滤数据。这意味着我们遍历列表并剔除 Java 应用程序中不需要的所有数据。一个条目没有太多数据,但在最坏的情况下,我们可能会讨论数百万行。

现在我有两个问题:

  1. 这是解决问题的正确方法吗?
  2. Cassandra 是否能够处理这么多数据?

【问题讨论】:

标签: java cassandra


【解决方案1】:

这当然行不通,因为 other_data 不是主键的一部分。如果我们将它添加到主键,我们会得到以下错误

这是 other_data 列上二级索引的最佳选择。在您的情况下,此索引将扩展,因为您始终提供分区键 (name),因此 Cassandra 不会命中集群中的所有节点。

使用 other_data 上的二级索引,您的第二个 SELECT 语句将成为可能。

现在您的数据模型还有另一个问题,即分区大小。实际上,如果您要每个名称每毫秒插入几个条目,这将无法扩展,因为每个名称的分区会增长得非常快...

如果插入分布在不同的分区键(不同的名称)上,那很好

【讨论】:

  • 感谢您的回答。这听起来是个好主意,我完全忘记了。将获得secondary index 的列的基数约为 250 个不同的值。插入是分布的,因为名称列具有高基数。列的总数也不会很高(大约 20 个)。你看到那里有什么问题吗?二级指标的数量重要吗?我认为我们将需要大约最大值。 10.
  • 在你的情况下,如果你有大量的name 这是完美的。 Cassandra 会将它分布在整个集群中,并且分区键的二级索引限制将像一个魅力一样发挥作用。 “二级指数的数量重要吗?” --> 二级索引越多,消耗的写入吞吐量就越多,这没有什么魔力。为了读取性能,只要提供分区键就可以了
猜你喜欢
  • 2011-01-13
  • 2021-03-15
  • 2013-04-17
  • 2012-11-05
  • 2013-08-02
  • 2014-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多