提问人:jernejt 提问时间:10/16/2023 最后编辑:jernejt 更新时间:10/18/2023 访问量:38
CQL 按时间范围检索时间序列数据
CQL retrieve timeseries data by time range
问:
我在不同的位置有传感器,每个传感器测量多个参数。每个传感器每天将有大约2数百万次测量。我需要按位置/时间范围进行查询,但指定的范围永远不会大于几天。一个示例查询是:
SELECT * FROM meas WHERE latitude=46.1 AND longitude=15.1 AND measurementTime >= 2023-10-15T23:00:00Z AND measurementTime <= 2023-10-16T01:00:00Z;
为了控制分区大小,我可以根据时间窗口拆分分区(我在某处读到这称为分桶) - 例如,按纪元后的第二天:
CREATE TABLE meas (
latitude double,
longitude double,
dayOfMeasurement int,
measurementTime timestamp,
param1 double,
param2 double,
param3 double,
etc...
PRIMARY KEY ((latitude, longitude, dayOfMeasurement), measurementTime)
) WITH CLUSTERING ORDER BY (measurementTime DESC)
现在我有两个选择:
- 在 WHERE 语句中使用 IN - 例如(假设从纪元到 2023 年 10 月 16 日有 19646 天):
SELECT * FROM meas WHERE latitude=46.1 AND longitude=15.1 AND dayOfMeasurement IN (19646,19645) AND measurementTime >= 2023-10-15T23:00:00Z AND measurementTime <= 2023-10-16T01:00:00Z;
- 或使用多个(上面示例中的两个)单独的查询并在客户端合并结果(我使用的是 datastax Cassandra 驱动程序)。
SELECT * FROM meas WHERE latitude=46.1 AND longitude=15.1 AND dayOfMeasurement=19645 AND measurementTime >= 2023-10-15T23:00:00Z AND measurementTime < 2023-10-16T00:00:00Z;
SELECT * FROM meas WHERE latitude=46.1 AND longitude=15.1 AND dayOfMeasurement=19646 AND measurementTime >= 2023-10-16T00:00:00Z AND measurementTime <= 2023-10-16T01:00:00Z;
这两个选项哪个更好?如果选项 2 更好 - 是否有一种标准方法可以在 datastax java 驱动程序中组合多个查询的结果? 还是应该使用其他数据模型?
答:
每个传感器每天将有大约2数百万次测量
我很好奇分区有多大。TBH 我建议除了天之外,还按小时细分它,因为这似乎每个分区的行数太多了。但是,如果它已经工作正常,那么它可能没问题。
使用多个(在上面的示例中为两个)单独的查询并在客户端合并结果
这是我推荐的方法。另一种方法(使用)的问题在于返回结果的顺序不一致。它将按日期和传感器分组,并按内部排序。但是分区的顺序将取决于令牌的哈希值,这不会是一致的。因此,我想说的是,一些客户端工作对于确保应用程序级别的一致行为是必要的。IN
measurementtime
你能进一步详细说明一下吗?
因此,一般来说,最好将分区大小保持在 1 或 2 MB 以下。保持每个分区的行数 <= 100,000 也是一种很好的做法。当行计数或分区大小超过这些值时,操作往往会变慢。
现在,这些都不是硬性的数学极限;只是一般准则。一个拥有 200 万行非常非常小的行的分区很有可能仍然可以工作。我什至见过大小为 10 MB 或更大的分区还可以。这实际上归结为有效载荷大小和访问模式。这就是我上面说“如果它已经起作用,那么它可能没问题”的意思。
评论