【问题标题】:Cassandra: Is this proper schema for the data model?Cassandra:这是数据模型的正确模式吗?
【发布时间】:2014-06-20 01:59:26
【问题描述】:

在基于传感器的应用程序中,每小时根据多达 30 个指标监控多达 30 万个对象,每个指标都有成功和失败计数器。

我的架构:

CREATE TABLE measurements(
  objId int,
  hour timestamp,
  metric text,
  succ int,
  fail int,
  PRIMARY KEY (objId, hour, metric));

数据保留期在 1 年内,这样表格将有 300k 行,每行有 24*360*30*2 列(单元格)。

通常的查询是获取在指定时间间隔(可能是几天、几周、几个月)和指定对象(范围从 1 到数百)内聚合的计数器值。

时间切片与列切片完全没问题,但检索多个对象有点麻烦,因为每个对象的行都由 objId 进行键控,这会导致多重获取。

我能想到的一般查询是:

select * from measurements where objId in (id1, id2, id3...idn) and hour >= <startTime> and hour < <endTime>;

当然,聚合必须在应用程序中手动完成。

问:在给定查询模式的情况下,这是构造数据的最佳方式吗?

最坏的情况是在一段时间内获得“整体”结果,这意味着将所有对象都考虑在内。从我的角度来看,这意味着全表扫描。有什么推荐的做法可以在不使用 MapReduce 的情况下执行此类任务?

【问题讨论】:

    标签: cassandra schema


    【解决方案1】:

    如果您知道通常会限制时间子集,并且每小时内可能的对象集可能很少,您可以考虑颠倒索引顺序,以便时间是第一个维度。这样,您会从一组受限的行中挑选出列,因此您仍然需要一个 multi-get,但如果查询所有对象是常见的,那么行数可能会更少。

    如果您通常查询/聚合到不同的时间粒度,您还可以以更高的时间粒度存储重复数据,例如每天、每周、每月等。这可以显着加快更大时间尺度的查询速度。反规范化是您在 Cassandra 中的朋友!

    您可以保留两个排序的索引,并根据您正在执行的查询类型选择索引。

    【讨论】:

    • 完全同意不同粒度的预聚合。但是有时间作为行键将失去时间线上非常需要的列切片。
    猜你喜欢
    • 1970-01-01
    • 2016-03-15
    • 2012-10-29
    • 1970-01-01
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    相关资源
    最近更新 更多