关于使用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中,以便以后可以用它们“重放”记录的流,获取历史结果(例如用于分析)以及使用特定的流来丰富/加入传入的流存储的数据值(例如,显示/比较当前能量值与一周前记录的能量值)。总之,我们基本上需要这些东西:
由于我们是cassandra的新手,我们目前不知道对表格和列进行建模的最佳方法是什么。
类似问题的大多数答案都不会面临使用未知模式的可能性(它们都假设存在时间戳,deviceId和double值)并且只面临主/部分密钥的问题。
我们读到了两个选项:
datapoints
,其中包含source-ID + day作为分区键的所有数据?但是我们如何在这里处理动态列?我们是否必须将整个元组序列化为单个公共列,例如将energydata和天气数据全部放在一个名为value
的列中。 所以我们有这张表:
CREATE TABLE datapoints (
sourceid bigint,
date text,
time timestamp,
value text,
PRIMARY KEY ((sourceid, date), time)
)
显然,我们不能在原始值上使用aggreate或其他函数(例如瓦特,安培或临时值)。
另一种可能性是为每个数据源创建一个表,例如使用day作为分区键:
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作为分区密钥是没有意义的,因为每个模式通常只有一个设备密钥。
但第二种解决方案看起来也不太合适。
我们希望有人也解决了类似问题并提出了一些建议吗?!
备注:我们不想使用其他时间序列db:)
答案 0 :(得分:1)
考虑使用地图作为数据值:
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)
)
答案 1 :(得分:0)
也许你可以混合使用这两种解决方案:
您可以创建一个包含所有信息的表格,如:
1
插入数据时,可能未指定许多列。但无论如何,cassandra不会在磁盘上存储NULL值。因此,此列表中包含5
和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)
);
列,并在示例中将变量空间作为表conditions
。
如果您使用cassandra&gt; = 3.0,yopu可以创建materialized视图来创建特定的表(如temp
和weather_2
)或创建其他方式来读取数据(重新指定分区例如关键)。
希望这可以帮到你。