TL;DR InfluxDB 技术提示 — 使用 Telegraf 进行时间序列预测

导航至

如果您熟悉 Telegraf,您就会知道,您可以使用单个 TOML 配置文件轻松配置这个轻量级收集代理,以从超过 180 个输入 收集指标,并将数据写入各种不同的输出和/或平台。您可能也知道 Telegraf 可以充当处理器、聚合器、解析器和序列化器。例如,您甚至可能熟悉 Starlark 处理器插件,它使您能够在 Telegraf 中执行各种数学运算。

毋庸置疑,Telegraf 非常棒。但是您知道您也可以使用 Telegraf 对您的时间序列数据执行预测吗?Telegraf Execd 处理器插件 是一个处理器插件,它使 Telegraf 可以用任何语言扩展,允许您根据需要处理您的数据。在这篇博文中,我们将学习如何使用这个插件来持续生成预测并执行异常检测。本教程随附的存储库可以在 这里 找到。这篇博客是对 Anais(我)和 Steven(Telegraf 团队的高级软件工程师)的 2020 年 11 月 InfluxDays 演讲 的回顾。

Forecasts were generated from data from a colleague's beer brewing setup

预测是从同事的啤酒酿造装置的数据生成的。原始数据在此处在 InfluxDB UI 中可视化。

关于 Telegraf Execd 处理器插件

Execd 处理器插件将外部程序作为单独的进程运行,将指标管道输送到进程的 STDIN,并从其 STDOUT 读取处理后的指标。程序必须接受标准输入 (STDIN) 上的 Influx 行协议,并将 InfluxDB 行协议中的指标输出到标准输出 (STDOUT)。您可以使用 Telegraf Execd Go Shim 来构建和贡献您自己的外部输入、处理器和输出插件。查看 外部 Telegraf 插件 以获取已可供您使用的外部插件列表。

标准错误上的程序输出将镜像到 telegraf 日志。

Program output on standard error is mirrored to the telegraf log

存储库中的 example.py 脚本是使用 Execd 处理器插件读取 STDIN 并使用 Python 将指标打印到 STDOUT 的简单示例。

它看起来像这样

# A simple processor. It reads stdin and writes it to stdout.
import sys
def main():
   for line in sys.stdin:
       print(line.rstrip())
       sys.stdout.flush()

if __name__ == '__main__':
   main()

执行简单 example.py 脚本的 Execd 处理器插件的 telegraf 配置如下所示

[[processors.execd]]
 command = ["python", "./processors/forecasting.py"]

数据集和时间序列预测目标

本教程的数据集来自 InfluxData 工程师 Luke,他使用 InfluxDB 来 监控他在家中的啤酒酿造装置。该数据集包含两种啤酒“haze_v5”和“bv_1”在发酵过程早期的温度数据。

Data from Luke's beer, haze_v5 visualized in the InfluxDB UI

Luke 的啤酒 haze_v5 的数据在 InfluxDB UI 中可视化

Data from Luke's beer, bv_v1 visualized in the InfluxDB UI

Luke 的啤酒 bv_v1 的数据在 InfluxDB UI 中可视化

在发酵的早期阶段,温度保持恒定非常重要。但是,您可以看到温度频繁波动。虽然多种来源会导致温度波动,但 Luke 可以通过向水桶中添加冰块来帮助最大限度地减少这些波动,水桶为他的酿造装置提供冷水流。这种冷水流是主要的温度调节器。考虑到这一点,选择预测程序是为了帮助 Luke 保持恒定的发酵温度。在选择可以帮助他做到这一点的算法时,考虑了以下几个因素

  • 温度波动几乎立即出现在数据集中。这意味着我们必须使用一种不需要大量数据进行训练的算法。
  • 预测应该在足够长的时间内保持准确,以便 Luke 能够对温度波动做出反应,给他足够的时间从他的酿造装置中添加或移除冰块(未来约 10 分钟)。
  • 我们想要检测可能表明需要注意或设备故障的异常温度峰值。

考虑到这些因素,我们选择使用 双指数平滑指数平滑 算法满足我们的要求,因为

  • 该算法可以使用少至 10 个点发出预测。
  • 该算法为短期预测期生成良好的预测。
  • 该算法不需要数据中的 季节性 - 数据中缺乏季节性。
  • 该算法的计算效率很高。我们每 10 秒对一小批数据进行预测。我们不希望该算法造成瓶颈。

我们决定我们还将计算残差,并使用 Telegraf Execd 处理器插件将残差也写入 InfluxDB。这样,如果 Luke 愿意,他可以监控残差,并在数据显着偏离预测时 设置警报。预测和残差计算在 forecasting.pyforecasting2.py 中实现。这两个脚本之间的差异是对双指数平滑实现的细微调整,如 此处 所述。具体来说,forecasting.py 实现了双指数平滑的指数趋势(或乘法)版本,而 forecasting2.py 实现了线性趋势(或加法)版本。使用双指数平滑的不同版本的两个预测来比较每个版本的准确性,以获得实验的乐趣。

使用 Telegraf Execd 处理器插件进行时间序列预测的优势

使用 Telegraf Execd 处理器插件进行预测具有几个优势。主要优势是这种实现非常灵敏。每次将新点写入 InfluxDB 时,都会生成预测。

A graph of the raw temperature data and the forecasts

原始温度数据和预测的图表。原始温度数据(蓝色),加法版本双指数平滑的预测(粉红色),乘法版本双指数平滑的预测(橙色)。

A graph of the residuals

残差图。残差预测版本(粉红色)和乘法预测版本(蓝色)。

由于每次将点写入 InfluxDB 时都会进行预测,因此预测似乎在复制原始数据。但是,如果您查看顶部图表中的最后一个点,您可以看到预测预测温度将继续下降(橙色和粉红色线急剧下降到右下角)——这是最近温度下降(以第一个异常标记)的结果。

但是,实际温度突然升高。预测是错误的,并且残差很高。值得注意的是,尽管第二个异常是更剧烈的温度下降,但这种下降是由第一次下降或温度异常上下文化的,这就是为什么残差没有第一次异常那么大。另请注意,残差图中的第一个异常存在的时间很短。残差的快速下降证明了预测对新输入数据的响应非常灵敏。在很长一段时间内看到残差飙升是非常出乎意料的。

通过这种方式,持续生成新的预测并监控残差,您可以更清楚地了解系统如何实时运行。反过来,它可以让您对异常情况做出更快的反应。

其次,您可能会问,“使用 Execd 处理器插件而不是运行 cron 作业有什么优势?” 首先值得一提的是,您可以使用 Telegraf 通过 Telegraf exec 输入插件 像 cron 作业一样运行脚本。如果您需要不频繁地运行外部进程,并且可以承受多次重启外部进程,则此插件非常有用。但是,如果您需要在批处理操作中频繁处理数千个数据点,那么您需要使用 Execd 处理器插件,因为它只运行一次外部进程,从而节省启动成本。

关于使用 Telegraf 进行预测和异常检测的最终想法

我希望这篇 InfluxDB 技术提示文章能够启发您利用 Telegraf Execd 处理器插件来生成预测并执行异常检测。如果您正在使用此插件或正在考虑贡献您自己的外部插件,请向我们寻求帮助并 分享您的故事!如果您希望贡献您自己的外部插件,请打开一个 拉取请求 以将其添加到外部 Telegraf 插件中。在评论区、我们的 社区网站 或我们的 Slack 频道中分享您的想法、疑虑或问题。我们很乐意获得您的反馈并帮助您解决遇到的任何问题!最后,如果您喜欢此内容,我鼓励您 注册 下一届 InfluxDays!