Flux 将多个表(Stream of tables)合并为一个表

68 阅读2分钟

当在 Flux 中使用 from() 查询 InfluxDB 数据返回的数据为包含零或多个表的流数据,官方原文为 stream of tables (很多地方翻译为“表流”)。

当这个表流里为多个表的时候,有些情况我们是需要把多个表合并为一个表后才能进行对应的操作。如:使用 sort() 进行排查,这个操作是对表流中的每个表中的数据进行排序,而不是对表流中所有数据进行排序。这时就需要把表流中的多个表中的数据合并为一个表后再使用 sort() 排序。

那么如何将表流中的多个表合并到一个表中能。经过翻看大量的官方文档,找到了下面两种方法。

在这之前需要使用 Telegraf 采集某个计算机中的 cpu 和 内存的数据并保存到 InfluxDB 中的名为 telegraf 的 bucket 中,以便后面供 Flux 使用。 cpu 数据保存到 名为 cpu 的 _measurement 中,内存数据保存到名为 mem 的 _measurement中(使用 Telegraf 的 # Memory Input Plugin 和 # # CPU Input Plugin 的默认配置即可)。

方法1:使用 group() 合并多个表

这有个需要注意的地方就是 _value 的类型,因为表流里返回的多个表中 _value 的值类型可能不一样,比如:使用 Telegraf 采集内存的数据中, available 为 long 类型,而 available_percent 为 double 类型。

就会出现下面这个错误提示:

schema collision: cannot group integer and float types together

示例代码,如下:

from(bucket: "telegraf")
    |> range(start: -60s)
    |> filter(fn: (r) => r._measurement == "mem")
    |> group()

方法2:使用 window(every: inf) 合并多个表

这个也不是很完美,可能也会有方法1中的那个问题。

另一个导致不能合并的原因是因为有可用于分组的字段中的值不同。

必须有 _time 列,不然会出现下面错误:

runtime error @20:14-20:32: window: missing time column "_time"

下面代码中删除了两个 _field 和 cpu 两个可用于分组的列。但,还有个 _measurement 列,这个列中当前有两个 cpu 和 mem 两类数据。所以,

示例代码,如下:

from(bucket: "telegraf")
    |> range(start: -20s)
    |> filter(fn: (r) => r._field == "usage_idle" or r._field == "available_percent")
    |> drop(columns: ["_field", "cpu"])
    |> window(every: inf)

参考资料: