【问题标题】:InfluxDB - Keep timestamp of record on downsamplingInfluxDB - 保持下采样记录的时间戳
【发布时间】:2020-10-15 04:55:53
【问题描述】:

使用的 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 downsampling


    【解决方案1】:

    到目前为止,我还没有找到仅使用 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' 这样做。

    【讨论】:

      猜你喜欢
      • 2019-07-30
      • 1970-01-01
      • 1970-01-01
      • 2015-04-10
      • 2021-04-15
      • 1970-01-01
      • 2018-01-17
      • 2016-03-29
      • 1970-01-01
      相关资源
      最近更新 更多