influxdb - InfluxDB - 保持下采样记录的时间戳
问题描述
使用的 InfluxDB 版本:1.8.0
给定一个时间序列数据库,用于存储来自物联网传感器(在不同位置)的温度。
例如每隔一分钟查询传感器。
现在可以使用查询过去一小时每个传感器的最高温度
select max(*) from temperatures where time >= now() - 1h group by location
name: temperatures
tags: location=collector
time max_temperature
---- ---------------
2020-06-24T17:41:34Z 34.8
name: temperatures
tags: location=outside
time max_temperature
---- ---------------
2020-06-24T17:43:34Z 23.4
我现在想在一段时间内保持每小时和每天的最高温度。
所以很自然我会使用保留策略和持续查询。
假设我想按小时存储一个月的最高温度:
show RETENTION POLICIES on iotsensors
name duration shardGroupDuration replicaN default
---- -------- ------------------ -------- -------
lastmonth 744h0m0s 24h0m0s 1 false
连续查询如下所示:
CREATE CONTINUOUS QUERY max_temperatures_per_hour ON iotsensors
BEGIN
SELECT max(temperature) INTO iotsensors.lastmonth.max_temperatures_per_hour FROM iotsensors.autogen.temperatures GROUP BY time(1h), location TZ('Europe/Berlin')
END
根据GROUP BY time(1h)
术语的性质,温度的准确时间会丢失。
尤其是当数据在第二步浓缩一整天时,FROM iotsensors.lastmonth.max_temperatures_per_hour GROUP BY time(1d)
分辨率变得更加粗糙。(设置为每天的午夜00:00:00
)
select max from iotmeasurements.last2years.max_temperatures_per_day where time >= now() - 4d group by location tz('Europe/Berlin')
name: max_temperatures_per_day
tags: location=collector
time max
---- ---
2020-06-21T00:00:00+02:00 80.9
2020-06-22T00:00:00+02:00 78.5
2020-06-23T00:00:00+02:00 101.2
name: min_max_temperatures_per_day
tags: location=outside
time max
---- ---
2020-06-21T00:00:00+02:00 21.8
2020-06-22T00:00:00+02:00 22.5
2020-06-23T00:00:00+02:00 22.8
我知道这是预期和记录的行为
https://docs.influxdata.com/influxdb/v1.8/query_language/explore-data/#group-by-time-intervals
但是,关于何时准确记录最大值的信息是我想保留的有价值的信息。
有没有办法在下采样时存储记录的确切时间戳?
我更愿意将时间戳保留在时间字段中,例如
tags: location=collector
time max
---- ---
2020-06-20T04:30:40Z 80.9
2020-06-21T04:22:00Z 78.5
2020-06-22T04:53:10Z 101.2
或者,第二个最佳解决方案是为每个下采样记录添加一个时间戳字段
time max timestamp
---- --- ---------
2020-06-20T00:00:00+02:00 80.9 2020-06-20T04:30:40Z
2020-06-21T00:00:00+02:00 78.5 2020-06-21T04:22:00Z
2020-06-22T00:00:00+02:00 101.2 2020-06-22T04:53:10Z
为此,我需要能够将时间查询到一个单独的字段中,不是吗。
但到目前为止我的尝试并不成功。我试过的是这样的:
SELECT max(temperature),time as timestamp FROM temperatures GROUP BY time(60m),"location"
如果这是解决我的问题的先决条件,我会考虑迁移到 InfluxDB 2.0。
解决方案
到目前为止,我还没有找到仅使用 InfluxDB 的解决方案。
最初的问题是基于这样一种误解,即在用于下采样的时间范围内始终存在一个最大值。给定一系列这样的数据点。
name: max_temperatures_per_day
tags: location=collector
time max
---- ---
2020-06-20T04:30:40Z 80.9
2020-06-21T04:22:00Z 78.5
2020-06-22T04:53:10Z 101.2
2020-06-22T05:33:10Z 73.3
2020-06-22T05:41:10Z 65.0
2020-06-22T05:53:10Z 48.2
2020-06-22T05:56:10Z 73.3
2020-06-22T10:30:10Z 54.3
2020-06-22T12:30:10Z 63.7
2020-06-22T18:03:10Z 101.2
2020-06-22T18:20:10Z 90.2
可以在一天中的第 4 个小时准确地确定一个具有最大值的时间点,2020-06-22T04:53:10Z 101.2
但在第 5 个小时,这是不可能的,因为最大值出现在 5:33 和 5:56。将数据下采样到一天 (24 小时) 的分辨率会使情况变得更糟,因为最大值 (101.2) 出现在当天上午 4 点 53 分和下午 6 点 03 分。应该保留这可能的多个时间点中的哪一个?
然而,使用 Kapacitor 执行持续查询,可以实现原始所需的结果。从这篇文章https://docs.influxdata.com/kapacitor/v1.5/guides/continuous_queries/开始,可以设置这样的查询
batch
|query('SELECT * FROM "iotmeasurements"."autogen".temperatures')
.period(1h)
.every(1h)
.groupBy('location')
.align()
|max('temperature')
.as('max_temp')
.usePointTimes()
|influxDBOut()
.database('iotmeasurements')
.retentionPolicy('lastmonth')
.measurement('max_temperatures')
.precision('s')
这将保持最大值首先出现的时间点。在下面的示例中,将保留上午 5:33 的数据点,并跳过上午 5:56 的相同值。
我不完全确定是否需要usePointTimes()
(https://docs.influxdata.com/kapacitor/v1.5/nodes/influx_q_l_node/#usepointtimes)。
如果在下采样时间范围内丢失最大值的后续出现记录是可以接受的,这可能是一个解决方案。尽管如此,为此需要运行第二个服务。添加一个额外的可能的故障转移点。使用 Kapacitor 的另一个缺点是似乎无法对过去执行下采样。
可以在连续查询之外执行GROUP BY time
这样SELECT max(temperature) INTO ... FROM temperatures WHERE time >= now() - 1w GROUP BY time(1h),"location"
的查询,以对 influxdb 本身内部过去的测量点进行下采样。
现在似乎有办法让 Kapacitor 'ticks' 这样做。
推荐阅读
- reactjs - 警告:列表中的每个孩子都应该有一个唯一的“key”道具,即使我传递了一个 key={}
- reactjs - Firefox add on & react, 如何访问浏览器/内容脚本
- flutter - 在 null 上调用了方法“[]”
- python - 为什么 pip 在当前目录而不是标准站点包位置安装包?
- svg - SVG ViewBox 未加载
- python - 为什么可以将一个类传递给 Python 的 sorted() 函数的 key 属性?
- android - 使用错误的“com/sun/istack/FinalArrayList”构建失败的异常
- java - 将图像插入单元格
- angular - 无法从 Angular 中的会话存储中检索值
- c# - 如何泛化可空类型