Cassandra:基于事件的时间序列的数据建模



我有一个数据建模问题。在我的应用程序中,我从几个不同的传感器读取数据,并将其存储在Cassandra中。传感器以非常不同的速率生成新的值:有些每隔一秒生成一次,有些每隔一个月生成一次。

此外,假设一个值在遇到下一个值之前一直有效。示例:传感器1在EPOCH后10秒发送值500,在EPOCH之后20秒发送值1000。EPOCH之后15秒的有效值需要是500。

由于有些速率会很高,而且我不想要无边界分区,所以我想应用bucketing。我正在考虑这样建模我的数据:

CREATE TABLE sensor_data (
sensor_id          text,
some_timing_bucket date,
measured_at        time,
value              double
PRIMARY KEY ((sensor_id, some_timing_bucket),  measured_at)
) WITH CLUSTERING ORDER BY (measured_at DESC);

应用程序需要提供的通常查询是";给我最后5/15分钟/1天的数据";,所以我会相应地选择CCD_ 1。甚至可能有多个不同bucket大小的表。

我无法理解的是:考虑我选择一天作为投篮间隔。现在我想检索一个十天没有更新的传感器的当前值。今天将没有分区,所以在我的应用程序层上,我需要发送九个查询,直到我回到足够远的时间,遇到当前有效的值为止,这些查询都不会产生任何结果。这听起来不是很有效,我很感激任何关于如何建模的意见。

附带说明:如果同一传感器的所有数据都在同一分区中,这不会是一个问题:只需询问时间戳小于范围查询开始时间的所有点,并将结果限制为一个。但这是不可行的,因为存在无界分区。

有一种更简单的方法可以通过使用一天存储桶来对数据进行建模。类似于:

CREATE TABLE sensor_data_by_day (
sensor_id text,
year int,
month int,
day int,
measured_at timestamp,
value double,
PRIMARY KEY ((sensor_id, year, month, day), measured_at)
) WITH CLUSTERING ORDER BY (measured_at DESC)

如果传感器每秒测量一个数据点,那么一天的最大可能值为86400(60秒x 60分钟*24小时(。每个分区86K行仍然是可管理的。

如果今天是2022年8月17日,并且您想检索前一天的数据,那么查询将是:

SELECT value FROM sensor_data_by_day
WHERE sensor_id = ?
AND year = 2022
AND month = 8
AND day = 16

假设目前是8月17日格林尼治标准时间08:30:00(自epoch以来为1660725000000ms(,检索最后15分钟(900秒前或1660724100000ms(的数据:

SELECT value FROM
WHERE sensor_id = ?
AND year = 2022
AND month = 8
AND day = 17
AND measured_at > 1660724100000

我想您会发现使用时间戳更容易,因为它在执行范围查询时提供了更大的灵活性。干杯

您可以使用这样一个更简单的表来完成此操作:

CREATE TABLE sensor_data (
sensor_id text,
day_number_from_1970 int,
measured_at timestamp,
value double,
PRIMARY KEY ((sensor_id, day_number_from_1970), measured_at)
) WITH CLUSTERING ORDER BY (measured_at DESC)

你可以查询这样的数据:

SELECT value 
FROM sensor_data
WHERE sensor_id = some_sensor_id
AND day_number_from_1970 = day_number
AND measured_at > start_time 
AND measured_at < end_time

使用单个int列,您应该可以减少磁盘上的数据,并获得良好的结果

最新更新