【问题标题】:InfluxDB2.0: How to sum up multiple time series with irregular time interval?InfluxDB2.0:如何总结多个时间间隔不规则的时间序列?
【发布时间】:2020-11-07 16:58:36
【问题描述】:

TL;DR 我正在使用 Influxdb v2.0 并使用 Influx 查询语法(如在 GUI 中)。我有多个数字 0/1 状态的系列(相同的_field,不同的标签),我想总结一下。问题是状态以不规则的时间间隔存储在数据库中,这意味着在任何时候都应该使用可能的最后一点来查询每个标签的实际实际值。我已经尝试使用“last”作为函数的聚合窗口,但最后只是为没有存储点的窗口删除表。无论如何我可以总结它们吗?我接受任何方法(包括导出数据并使用其他语言脚本代替 lmao)。提前谢谢你。


情景

我的团队早些时候实施了一个登记/退房系统,电话号码代表每个人的真实世界事件,并决定使用 InfluxDB v2.0 作为数据库(我们选择它以便我们可以通过格拉法纳轻松)。我有一个存储签入/签出值的存储桶,所有相同的模式。架构如下:

measurement: 'user'
tags: [phone, type]     // type is either ['normal', 'staff']
value: 0 or 1           // 0 for checking out event, 1 for checking in event

每当有人签入该事件时,就会插入一个值为 1 的点,反之亦然,每当有人签出该事件时,就会插入一个值为 0 的点。请记住,如果用户决定再次触发 api,就像之前已经签入并再次签入一样,则该点可能会重复(尽管我们认为这具有相同的状态 1)。所以数据就像一个数字0/1状态,但点的时间间隔不规则,每个电话号码有一条曲线。对于我们来说,相同的电话号码但类型不同的人被视为不同的人。

项目已经部署,我们的任务是对数据进行后处理。问题是在整个时间内可视化事件人口的图表。从数学的角度来看,这应该可以通过将每个人的所有状态(0/1 线)随时间相加来轻松解决。我首先在 Influx 查询中尝试了这样的事情:

from(bucket: "event_name")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_measurement"] == "user")
  |> group(columns: ["type"])
  |> aggregateWindow(every: v.windowPeriod, fn: sum, createEmpty: true)
  |> yield()

结果看起来很有希望,人口图有 2 种颜色类型的正常和人员。但是仔细看,Influx 的 sum 函数实际上是对每个窗口中每个点的 _value 求和。这意味着对于一些没有意义的窗口,sum 函数实际上并没有总结数据库中的每个人。目标是对那些没有点的窗口的实际 _value 求和(这些窗口的 _value 应该与最后一个点的 _value 相同,例如,就像我在晚上 7 点签到并且 _value 应该是 1 所有晚上 7 点之后的时间,即使某些窗口也没有任何意义)。然后我尝试了这样的事情:

from(bucket: "event_name")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_measurement"] == "user")
  |> aggregateWindow(every: 1m, fn: last, createEmpty: true)
  |> fill(usePrevious: true)
  |> group(columns: ["type"])
  |> aggregateWindow(every: 1m, fn: sum)
  |> yield()

我对每个窗口使用最后一个点,然后用空_value 填充窗口和前一个可能的点,然后再次总结每个窗口的_value。但是后来我发现last函数实际上是drop empty table,意思是没有点的窗口被删除了(createEmpty然后就没用了)。然后问题的范围是我必须找到像last 这样的函数,但不删除空表。我试过reduce 来创建我自己的逻辑,比如last,但遗憾的是它并没有像我想要的那样进行(可能是我编码错误)。

如果您有任何想法,请提供帮助。非常感谢。

【问题讨论】:

    标签: time-series influxdb influxdb-2


    【解决方案1】:

    Nvm,我找到了解决方案,这里适用于那些处于相同情况的人,虽然性能不是很优雅,但这是我发现它唯一有效的查询。

    from(bucket: "event_name")
      |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
      |> filter(fn: (r) => r["_measurement"] == "user")
      |> aggregateWindow(every: 1m, fn: last, createEmpty: false)
      |> aggregateWindow(every: 1m, fn: mean, createEmpty: true)
      |> fill(usePrevious: true)
      |> fill(value: 0.0)
      |> group(columns: ["type"])
      |> aggregateWindow(every: 1m, fn: sum, createEmpty: false)
      |> yield(name: "population")
    
    1. 我首先使用last 来获取每个窗口的最新状态(尽管last 实际上会删除空表,所以无论如何设置createEmpty: true 是没有用的)
    2. 然后对于没有任何点的窗口,我使用meancreateEmpty: true 以便为空窗口创建带有空_value 的点。对于实际有实际点的窗口,mean 不应更改值,因为每个窗口应该只有 1 个点,因为我们之前使用了 last。这里使用mean 的目的只是为空窗口创建空点。这里的步骤只是找到一个不做任何事情的函数,它不会删除由createEmpty 创建的空表。仅供参考,我尝试了很多功能,包括制作我自己的自定义函数,如 reducemap,但它们确实删除了空表(甚至不允许分配 null),我什至为 @ 创建了一个空函数,如 fn: (tables=<-, x) => tables 987654335@ 但无论如何它都会删除空表。所以mean 是我最好的选择,尽管副作用是我的值从 int 变为 float。
    3. 我在这里使用fill 将空点替换为最后一个窗口中的值。这就是为什么我试图从最后一步将空窗口中的点分配为 null,而 mean 只能这样做。第二个fill 用于那些应该代表0-state 的早期空窗口。
    4. 然后group 按类型和summing 他们应该是我要寻找的结果

    希望以后能帮到和我一样情况的人

    【讨论】:

    • 我也面临同样的问题,我想知道我们是否最好使用 InfluxQL ?
    • 我同意,我们应该更好地使用 InfluxQL。文档和语法还不够完善。甚至 InfluxDB v2.0 本身也不太方便,比如为什么我必须在 systemctl 中将它设置为服务,而 v1.8 不需要(文档也没有提到这一点)。我猜这个 v2.0 不适合新手。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-02
    • 2019-12-26
    • 2021-01-08
    • 2020-03-25
    • 2015-06-03
    • 1970-01-01
    • 2011-04-23
    相关资源
    最近更新 更多