TL;DR InfluxDB技术技巧——监控任务和找到卡迪纳尔性失控的源头
作者:Anais Dotis-Georgiou / 产品,用例,开发者
2020年12月03日
导航至
因此,您正在使用InfluxDB Cloud,并向您的账户写入数百万个指标。您还在运行各种下采样和数据转换任务。无论您是在InfluxDB上构建物联网应用还是用InfluxDB监控您的生产环境,您的时间序列操作终于顺利运行。您希望保持这种状态。您可能是免费计划云用户或基于使用量的计划用户,但无论如何,您都需要对实例大小有可见性,以便管理资源和成本。使用InfluxDB操作监控模板来防止卡迪纳尔性失控并确保任务成功。
操作监控模板是什么?
如果您是InfluxData的新用户,InfluxDB模板是一组预先配置和可共享的仪表板、任务、警报、Telegraf配置等。您通过从社区模板复制感兴趣模板的URL并将其粘贴到UI中应用它们。今天,我们将应用操作监控模板来监控我们的InfluxDB Cloud账户的卡迪纳尔性和任务执行。
<figcaption>通过UI应用模板的一个示例。导航到设置页面上的模板选项卡,粘贴要应用的模板的YAML或JSON链接.</figcaption>
操作监控模板包含以下资源
-
- 1 桶:卡迪纳尔性
- 1 任务:每小时运行一次的cardinality_by_bucket。此任务负责计算所有桶的卡迪纳尔性并将计算结果写入卡迪纳尔性桶。
- 1 标签:operation_monitoring。此标签有助于您在UI中更容易地找到此模板的资源。
- 2 变量:桶和度量。
- 2 仪表板
-
- 任务摘要仪表板。此仪表板显示有关任务运行、成功和失败的信息。
- 卡迪纳尔性探索器。此仪表板帮助您可视化所有桶的系列卡迪纳尔性。深入到度量卡迪纳尔性以解决您的卡迪纳尔性失控问题。
任务摘要仪表板如何帮助我?
任务摘要仪表板和卡迪纳尔性探索器仪表板都可以用来监控您的特定任务执行状态和系列增长。任务摘要仪表板看起来像这样
<figcaption> 任务概览仪表板的示例。它提供有关过去一小时由时间范围下拉配置(粉色方块)控制的任务运行的详细信息。</figcaption>
仪表板的前三个单元格允许您轻松评估指定时间范围内所有任务的执行情况。从这张截图我们可以看到,有80个任务运行失败。第二行的单元格允许我们轻松按任务排序,以确定时间范围内每个任务最成功和失败运行的次数。它提供错误率和任务ID。
<figcaption> 任务概览仪表板的其他部分。它提供有关过去一小时内任务运行的详细信息。</figcaption>
仪表板还包括一个错误列表单元格。该单元格包含有关所有失败运行的信息,包括每个运行ID的个别错误消息。您可以使用此单元格确定任务失败的原因。在“错误率随时间变化”下方,您可以轻松确定失败的任务数量是否在增加。线性线表示同一组任务在失败,而指数线则表明越来越多的任务在失败。
<figcaption> 任务概览仪表板的其他部分。它提供有关过去一小时内任务运行的详细信息。</figcaption>
任务概览仪表板的最后一个单元格,每个任务的最后成功运行,帮助您确定任务何时失败,以便您可以更容易地调试任务。现在我们已经审查了任务概览仪表板的功能,让我们来看看基数探索器仪表板。
使用自己的任务警报补充模板
如果您正在运行对您的时间序列用例至关重要的任务,我建议设置警报以监控这些任务的失败情况。使用任务概览仪表板来帮助您找到您想要警报的任务的关联任务ID。现在我们需要将状态转换为数值,以便为失败任务创建阈值警报。接下来,导航到数据探索器。使用以下Flux脚本来将状态转换为布尔值:map() 函数
from(bucket: "_tasks")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["taskID"] == "05ff8e19b32dc000")
|> map(fn: (r) => ({ r with status_bool: if r.status == "success" then 1 else 0}))
点击另存为按钮,将其转换为警报。然后创建阈值警报,如果状态布尔值小于1,则发出警报。
有关创建警报的更多信息,请参阅下面的“使用自己的基数警报补充模板”部分,或使用任务和检查监控InfluxDB。
基数探索器仪表板如何帮助我?
基数探索器仪表板提供InfluxDB实例中每个桶的基数。
<figcaption> 这是Cardinality Explorer Dashboard的示例。它提供了有关您InfluxDB实例基数的信息。标签允许您通过下拉配置(橙色)可视化指标。</figcaption>
仪表板上方的变量允许您轻松切换桶和度量。
- 第一个单元格中的图表,按桶的基数,允许您一眼监视所有桶的基数。我们可以看到,我们的基数保持在同一范围内。所有桶的基数具有很小的标准偏差是一个好兆头。这使我们能够验证我们没有系列基数问题。在这种情况下,可能有必要在桶上创建额外的警报,以便在您的基数超过预期标准偏差时通知您。基数下降可能是数据成功过期或数据删除成功的证据。基数激增可能是新导入的数据与即将被删除的旧数据之间暂时重叠的结果。也可能是由于一个重要事件。
- 第二个单元格,顶级桶,提供了最大桶及其基数的表格视图。
- 第三个单元格,按度量基数,允许您针对每个桶的特定度量进行深入挖掘,所选的桶和度量变量。如果您遇到运行中的系列基数问题,这将特别有用。
- 使用最后一个单元格(未显示),按标签基数,以查找无界标签。值得注意的是,执行这些计算的Flux脚本相当巧妙。
在下一节中,我们将了解cardinality_by_bucket任务是如何工作的,以帮助我们了解这些单元格是如何在查询遵循相同逻辑的情况下产生这些基数数据的。
基数任务是如何工作的?
基数任务,cardinality_by_bucket,由以下Flux代码组成
import "influxdata/influxdb"
buckets()
|> map(fn: (r) => {
cardinality = influxdb.cardinality(bucket: r.name, start: -task.every)
|> findRecord(idx: 0, fn: (key) =>
(true))
return {
_time: now(),
_measurement: "buckets",
bucket: r.name,
_field: "cardinality",
_value: cardinality._value,
}
})
|> to(bucket: "cardinality")
Flux influxdata/influxdb包目前包含一个Flux函数,influxdb.cardinality()。此函数返回特定桶内数据的系列基数。函数buckets()返回一个桶列表。这里的map()函数实际上是“迭代”桶名称列表。它使用findRecord()在一个自定义函数中,cardinality
,以返回每个桶的系列基数。返回语句创建一个新的表,其中对应的r.name作为字段键,cardinality._value
作为字段值。然后,这些数据写入我们的“cardinality”桶。
如果您想更详细地了解findRecord()函数,请参阅如何使用Flux和InfluxDB提取值、可视化标量和执行自定义聚合。
用您自己的基数警报补充模板
为了充分利用此模板的益处,我建议基于基数桶设置一个基数阈值警报。创建警报最快的方法是通过用户界面。在用户界面导航到警报选项卡。首先查询您的基数。尽管在图形可视化中很难可视化我们的基数数据,但默认的警报用户界面可视化类型,我可以悬停在点上或通过原始数据视图来更好地了解我的数据。
我发现我的基数数据可以大致分为三个范围。接下来,我将配置围绕这些范围的警报。如果我的桶中的基数超过这三个阈值之一,我将收到一个警报。
此类型的警报可以帮助您防范在InfluxDB Cloud中达到基数限制。具体来说,免费套餐和使用基于使用量的套餐用户希望在接近10,000个基数和1M初始基数限制的80%时收到警报。您还可能考虑创建一个任务,将所有桶的基数求和,并对总基数进行警报。
如果您发现您的基数显著增长,您可以决定是否需要请求更高的基数限制,或者您是否需要下采样历史数据。要请求更高的基数限制,请点击InfluxDB UI右上角的“立即升级”按钮。
请参阅解决使用InfluxDB时的系列基数失控问题,InfluxDB模式设计和数据布局文档,以及InfluxDB数据布局和模式设计最佳实践,以获取有关管理基数和最佳模式设计的更多信息。
如果您想了解如何使用用户界面创建警报,请参阅使用InfluxDB的任务和检查进行监控和如何使用InfluxDB监控状态。
顺便说一句,如果您对了解为什么基数不会成为未来InfluxDB用户的关注点感兴趣,我鼓励您阅读宣布InfluxDB IOx - 使用Rust和Arrow构建的InfluxDB未来核心。
关于InfluxDB操作监控模板的最终想法
请注意,直到cardinality_by_bucket
任务运行,基数探索仪表板将是空的。它每1小时运行一次,因此可能需要一段时间才能在该仪表板中填充有意义的数据。但是,如果您需要立即可视化您的基数数据,您可以将基数_by_bucket任务中的脚本改作他用,并选择您希望收集基数数据的时间范围。然后,如果您希望,您可以使用to()函数将基数数据写入基数桶。使用subDuration()函数创建正确的时间戳。
import "influxdata/influxdb"
import "experimental"
time = experimental.subDuration(
d: 7d,
from: now(),
)
buckets()
|> map(fn: (r) => {
cardinality = influxdb.cardinality(bucket: r.name, start: -7d)
|> findRecord(idx: 0, fn: (key) =>
(true))
return {
_time: time,
_measurement: "buckets",
bucket: r.name,
_field: "cardinality",
_value: cardinality._value,
}
})
希望这篇InfluxDB技术技巧文章能为您提供工具,帮助您高效监控InfluxDB云实例、成功的时间序列操作以及控制成本的能力。如果您计划使用运营指标模板,请向我们寻求帮助并分享您的经历!在评论部分、我们的社区网站或Slack频道中分享您的想法、担忧或问题。我们非常乐意收到您的反馈并帮助您解决遇到的问题!特别感谢@nathanielc和@aanthony1243为这个模板贡献了两个仪表板。