Cassandra:具有动态 columns/sources 的时间序列

Cassandra: time series with dynamic columns/sources

有很多关于用 cassandra 存储时间序列的问题,但没有一个适合我们的问题,因为它们都假定一个固定的数据源和已知的列名。

关于我们的问题: 我们正在开发一个流数据引擎,它可以连接到不同的数据源,引擎以连续流的形式接收数据。 因此,我们有两个数据源,例如 energyweather。每个传入流(或数据源)都有自己唯一的键,通常也有自己的模式,例如:

ID 1 架构 energy 可能有这个流:

timestamp | volts | amps | watts | state
1467795743173 | 210.4 | 2.3 | 290  | "up"
1467795744173 | 212.1 | 2.1 | 287  | "up"
1467795745173 | 213.1 | 2.2 | 242  | "up"
...

ID 2 架构 weather 可能有这个流:

ts | condition | temp
1467795740632 | "cloudy" | 33.1
1467795741381 | "cloudy" | 33.4
...

现在我们想提供将流存储到 cassandra 中的可能性,以便稍后可以将它们用于 "replay" 记录的流,获取历史结果(例如用于分析)和 enrich/join 具有特定存储数据值的传入流(例如 show/compare 当前能量值与一周前记录的能量值)。总之,我们基本上需要这些东西:

由于我们是 cassandra 的新手,我们目前不知道什么是对 table 和列建模的最佳方法。

大多数类似问题的答案都不会面临未知模式的可能性(他们都假设有时间戳、deviceId 和双精度值),只会面临 primary/partion 键的问题。

我们读到了两个选项:

  1. 我们要不要单曲table,例如datapoints,其中包含所有以source-ID+day作为分区键的数据?但是我们如何处理这里的动态列呢?我们是否必须将整个元组序列化为一个公共列,例如将能源数据和天气数据都放在一个名为 value 的列中。

所以我们有这个 table:

CREATE TABLE datapoints (
 sourceid bigint,
 date text, 
 time timestamp, 
 value text,
  PRIMARY KEY ((sourceid, date), time)
 )

显然,我们不能对原始值(例如瓦特、安培或温度)使用聚合或其他函数。

另一种可能性是为每个数据源创建一个 table,例如使用日期作为分区键:

CREATE TABLE energy_1 (   
 date text, 
 time timestamp, 
 volts double,
 amps double,
 watts double,
 state text,
  PRIMARY KEY (date, time)
 )

CREATE TABLE weather_2 (
 date text, 
 time timestamp, 
 condition text,
 temp double,
  PRIMARY KEY (date, time)
 )

由于数据将使用日期进行分区,是否可以获取例如一周还是这不可能?尽管可能有不止一个数据源具有相同的模式(例如两个能源数据源),但我们并不知道这一点,而且这种情况很少见。所以使用设备 ID 作为分区键是没有意义的,因为大多数情况下每个模式只有一个设备键。

但是第二种方案看起来也不太合适table。

我们希望有人也解决了类似的问题并提供一些建议?!

备注:我们不想使用其他时间序列数据库:)

也许您可以混合使用这两种解决方案:

您可以创建一个包含所有信息的 table,例如:

CREATE TABLE datapoints (
    sourceid bigint,
    date text, 
    time timestamp, 
    value text,
    volts double,
    amps double,
    watts double,
    state text,
    condition text,
    temp double,
    PRIMARY KEY ((sourceid, date), time)
);

插入数据时,很多列可能没有指定。但无论如何,cassandra 不会在磁盘上存储 NULL 值。因此,此 table 列 conditionstemp 指定为 mutch space as table weather_2 在你的例子中。

如果你使用 cassandra >= 3.0,yopu 可以创建 materialized 视图来创建特定的 tables(比如 energy_1weather_2)或者以其他方式创建读取数据(例如重新指定分区键)。

希望对您有所帮助。

考虑为您的数据值使用地图:

CREATE TABLE datapoints (
  sourceid bigint,
  date text, 
  time timestamp, 
  values map<text, text>,
  PRIMARY KEY ((sourceid, date), time)
 )

您还可以将地图用于不同的数据类型:

CREATE TABLE datapoints (
  sourceid bigint,
  date text, 
  time timestamp, 
  strvalues map<text, text>,
  intvalues map<text, int>,
  decvalues map<text, decimal>,
  PRIMARY KEY ((sourceid, date), time)
 )