【发布时间】:2016-11-08 09:04:03
【问题描述】:
关于使用 cassandra 存储时间序列有很多问题,但没有人适合我们的问题,因为它们都假设一个固定的数据源和已知的列名。
关于我们的问题:
我们正在开发一个流数据引擎,它可以连接到不同的数据源,引擎以连续流的形式接收数据。
因此,例如,我们有两个数据源,分别称为 energy 和 weather。每个传入流(或数据源)都有自己的唯一键,通常还有自己的架构,例如:
源 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 中,以便以后可以使用它们来“重播”记录的流、获取历史结果(例如用于分析)以及丰富/加入具有特定存储的数据值(例如,显示/比较当前能量值与一周前记录的能量值)。总之,我们基本上需要这些东西:
- 按顺序读取某个特定的源 ID
- 获取某个源 ID 的范围(例如,从 2016 年 7 月 6 日 10:00 到 11:00 之间从设备 ID 2 获取所有内容)
- 保存任意列(除了固定的时间戳列),因为我们事先不知道架构。
由于我们是 cassandra 的新手,我们目前不知道对表和列建模的最佳方法是什么。
类似问题的大多数答案都不会面临未知架构的可能性(他们都假设存在时间戳、deviceId 和双精度值),而只会面临主键/分区键的问题。
我们了解到两种选择:
- 我们是否应该只有一个表,例如
datapoints,包含所有以source-ID+day 作为分区键的数据?但是我们如何处理这里的动态列呢?我们是否必须将整个元组序列化为单个公共列,例如将能源数据和天气数据放在一个名为value的列中。
所以我们有这张表:
CREATE TABLE datapoints (
sourceid bigint,
date text,
time timestamp,
value text,
PRIMARY KEY ((sourceid, date), time)
)
显然,我们不能对原始值(例如瓦特、安培或温度)使用聚合或其他函数。
另一种可能性是为每个数据源创建一个表,例如使用日期作为分区键:
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)
)
由于数据将使用日期进行分区,是否可以获取例如一个星期还是不可能的?尽管可能存在多个具有相同模式的数据源(例如两个能源数据源),但我们并不知道,而且这种情况很少见。所以使用 device-id 作为分区键是没有意义的,因为每个模式大多只有一个设备键。
但是第二种解决方案看起来也不是很合适。
希望有人也解决过类似的问题,给点建议?!
备注:我们不想使用其他时间序列数据库:)
【问题讨论】:
标签: cassandra cql database nosql