卡桑德拉时间序列数据(正确方法?)

时间:2016-01-25 15:46:00

标签: java cassandra

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

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 [无效查询] message =“PRIMARY KEY列”other_data“无法限制(前一列”start“受非EQ关系限制)”

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

我们解决问题的方法是使用上面提到的(第一个)范围查询选择所需的(时间序列)数据,然后在我们的Java应用程序中过滤数据。这意味着我们浏览列表并将我们在Java应用程序中不需要的所有数据踢出去。一个条目没有太多数据,但在最坏的情况下我们会谈论数百万行。

现在我有两个问题:

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

1 个答案:

答案 0 :(得分:0)

  

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

这是 other_data 列上二级索引的最佳位置。在您的情况下,此索引将缩放,因为您始终提供分区键(名称),因此Cassandra不会命中群集中的所有节点。

使用 other_data 上的辅助索引,您的第二个SELECT语句将是可能的。

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

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