使用InfluxDB通过降采样查看趋势聚合值
作者:Kristina Robinson / 产品,用例,开发者
2021年1月25日
导航至
(更新: InfluxDB 3.0 已远离Flux和内置任务引擎。用户可以使用外部工具,如基于Python的Quix,在InfluxDB 3.0中创建任务。)
InfluxDB擅长捕获多种类型的指标,并允许最终用户将这些指标聚合到自定义的时间分组中,无论是监视物联网设备每10分钟的性能,还是GitHub存储库问题每周关闭,或者秒级的Web性能指标。仪表板可以在一瞥之间提供这些信息,精确到您设定的间隔。但下一级是什么?当你已经调优了你的仪表板,并捕获了你想要的数字时,会发生什么?你如何观察它们随时间的变化?这就是降采样和趋势变得至关重要的地方,可以将你的目标提升到下一个层次。InfluxDB使你能够轻松地确定要趋势的指标,跟踪它,并绘制它。
为了演示如何随时间趋势值,本博客文章将介绍使用SpeedTest社区模板,每分钟将互联网连接速度下载到InfluxDB中。社区模板有一个仪表板显示当前的上传和下载速度。然后我们将计算5分钟间隔内的最小、平均和最大速度。需要在本地计算机上安装SpeedTest-CLI可执行文件。
使用InfluxDB与SpeedTest社区模板
要安装InfluxDB中的SpeedTest社区模板,请点击设置,模板,并在资源清单文件的第2行输入以下URL
https://github.com/influxdata/community-templates/blob/master/speedtest/speedtest.yml
配置以下环境变量:INFLUX_HOST
(设置为您的云URL),INFLUX_ORG
(通过点击人图标获取),以及INFLUX_TOKEN
(可以在设置下的令牌中生成,必须至少是speedtest桶的写令牌)。环境变量可以在shell资源文件中设置,直接导出(export INFLUX_ORG=InfluxData)或使用用户环境变量设置(Windows操作系统)。
按照弹出窗口“设置说明”中的说明(点击 数据,Telegraf,设置说明)在本地机器上启动 Telegraf。
您应该有一个看起来与这个相似的板子
访问生成仪表板单元格的Flux查询
我们要选择您想要追踪趋势的值背后的查询 之后。在这个例子中,是下载速度。
打开标有“Speedtest”的仪表板。
配置标有“下载”的单元格。
查询编辑器打开,因此您可以选择并复制整个查询
from(bucket: "speedtest")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "exec_speedtest")
|> filter(fn: (r) => r["_field"] == "download_bandwidth")
|> map(fn: (r) => ({r with _value: r._value / 1000000.0}))
|> yield(name: "last")
在InfluxDB中使用Flux可视化多个聚合
下一步涉及使用取现有指标但将其写入另一个桶的查询。或者,聚合,然后写入。为什么这样做?有两个原因
- 桶可能有一个有限的保留策略。例如,源数据可能仅可用30天。我们想要追踪超过30天,因此将数据写入具有更长保留策略的不同、更小的桶可以让我们更长时间地保留追踪数据。
- 我们可以写入原始桶中不可用但源自源数据的聚合数据。这允许我们对聚合数据进行一些有趣的工作。
作为附带说明,您可以直接从仪表板可视化聚合数据。然而,这篇博客旨在解决本身对操作就有意义的聚合数据,并且可能需要比初始源更长时间可用。
让我们追踪三个聚合:下载速度的最小值、最大值和平均值。
点击“探索”(数据探索器)。
点击右侧的脚本编辑器按钮。
粘贴上面的复制查询。
从这个查询计算三个新值:最小值、最大值和平均值。您可以使用InfluxDB提供的任何聚合函数,但为了示例简单,让我们保持简单。首先,将复制的查询分配给DATA
标签。这将为后续使用保存返回的数据集。接下来,使用那个DATA
并将管道操作符发送到每个三个函数,以及yield()函数来显示结果。在yield()函数中使用不同的名称将允许每个提交显示多个值。
DATA = from(bucket: "speedtest")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "exec_speedtest")
|> filter(fn: (r) => r["_field"] == "download_bandwidth")
|> map(fn: (r) => ({r with _value: r._value / 1000000.0}))
DATA
|> mean()
|> yield(name: "mean")
DATA
|> min()
|> yield(name:"min")
DATA
|> max()
|> yield(name:"max")
在此处点击提交将显示图表上的三条数据线,或使用表格显示三组数据。您还可以查看原始数据并查看生成的数据。您还可以通过在新表中删除不需要长期保留的标记值来进一步清理这些数据。您可以在顶部部分添加“drop”函数并删除您不希望保留的任何字段。
使用InfluxDB编写计算最小值、最大值和平均下载速度的下采样任务
现在我们已经查询了我们想要追踪的值,我们准备将它们写入一个新的桶。让我们创建一个名为“speedtest-downsampled”的新桶。
将上述的 yield() 函数改为写语句,使用 to() 函数。此外,使用 set() 函数为每个由 min()、mean() 和 max() 函数计算出的值创建匹配的名称(“min”、“mean”、“max”)在“_field”条目中。这些硬编码的“_field”条目将成为在过滤和显示最终图表时查找存储在_value中的值的键。
最后,让我们看看 _time 列。Min() 和 max() 都解析为单个记录,这意味着它们各自将有一个自己的 _time 值(在不同的时间发生)。然而,mean() 是许多记录的聚合,它将无法访问单个行的时间值。但是,为了抓拍这三个值并将它们分组在一起,我们希望将它们比较在任何我们选择的间隔上。因此,让我们通过使用 map() 函数为所有三个聚合行分配相同的时间值。使用 now() 函数并将它保存到所有三个函数中,为这个查询的执行值分配一个 _time 值。这允许基于相同的 _time 和 _measurement 字段进行查询。记住,使用 to() 函数写入桶的所有行都必须具有以下字段的值:_measurement、_field 和 _time。我们从第 3 行的过滤器函数中获得 _measurement。我们使用 set() 函数分配 _field 值。现在我们正在分配 _time 值。
DATA = from(bucket: "speedtest")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "exec_speedtest")
|> filter(fn: (r) => r["_field"] == "download_bandwidth")
|> map(fn: (r) => ({r with _value: r._value / 1000000.0}))
|> drop(columns:["_start", "_stop", "host"])
time = now()
DATA
|> mean()
|> map(fn: (r) => ({r with _time: time}))
|> set(key:"_field", value:"mean")
|> to(bucket:"speedtest_downsampled")
DATA
|> min()
|> map(fn: (r) => ({r with _time: time}))
|> set(key:"_field", value:"min")
|> to(bucket:"speedtest_downsampled")
DATA
|> max()
|> map(fn: (r) => ({r with _time: time}))
|> set(key:"_field", value:"max")
|> to(bucket:"speedtest_downsampled")
通过点击 提交 按钮来测试这个查询。在查询构建器中,点击 Query2,选择 FROM ‘speedtest_downsampled’,过滤‘exec_speedtest’,然后点击 提交。
选择 Query1 标签,点击 另存为。输入任务的名称,任务应运行的频率,并选择‘speedtest_downsampled’桶。
从 任务 菜单,现在可以编辑任务。
- 从任务的底部移除额外的 to() 函数。这是一个已知问题,每个创建的任务都会写入上一屏幕指定的桶。由于在保存的查询中已经包含 to() 函数,这个添加的语句可以删除。
- 验证任务顶部的 timeRangeStart,在第 1 行上面的第 1 行。使用 ms、s、m、h、d 或 y 来指定时间间隔,或选择特定日期。在这个例子中,-5m 用于开始时间,以便任务收集过去 5 分钟的数据。
- 通过确认任务声明中 "every:" 后的值来验证任务的运行频率(如上第 2 行所示)。
- 点击 保存。
在 InfluxDB 仪表板中结合任务输出
我们几乎完成了!新的桶(speedtest_downsampled)将开始累积三个聚合数据值的快照。随着时间的推移查询它们并将其添加到仪表板中。返回到 数据探索器。
打开一个新的查询标签并点击 脚本编辑器。粘贴这个简单的查询以查看 'speedtest_downsampled' 桶,按 _time 字段分组,这很合适,因为聚合字段具有相同的时间戳。
from(bucket: "speedtest_downsampled")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "exec_speedtest")
|> group(columns : ["_time"])
点击 提交,然后使用表格图或原始数据视图,查看每个时间戳的三条记录。
一次查看最多三条记录的最佳图表类型是图形(线形)可视化。它需要命名yield()函数来显示多个系列。如前所述,使用脚本编辑器添加命名yield()函数
DATA = from(bucket: "speedtest_downsampled")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "exec_speedtest")
|> filter(fn: (r) => r._field == "mean" or r._field == "min" or
r._field == "max")
点击 另存为,仪表板单元格,选择 速度测试仪表板,并将单元格命名为“趋势下载速度”以使新的图形可视化出现在现有仪表板上。
调整单元格在仪表板上的位置,我们就算完成了。
关于趋势、在单个任务中执行多次聚合以及在InfluxDB中可视化的最终思考
我希望这个教程能帮助你进行降采样和可视化工作。一如既往,如果你遇到困难,请在我们社区网站或Slack频道上分享。我们很乐意获取你的反馈并帮助你解决问题。
鸣谢: Ignacio Van Droogenbroeck Anais Dotis-Georgiou