【博客675】prometheus生产上易犯的错误

这篇具有很好参考价值的文章主要介绍了【博客675】prometheus生产上易犯的错误。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

prometheus生产上易犯的错误

Mistake 1: Cardinality bombs

这是每个人在开始使用 Prometheus 时至少会遇到一次的经典陷阱。一旦您发现 Prometheus 基于标签的数据模型的有用性,您可能会想按各种有用的标签维度来拆分指标,直到您创建的时间序列超出 Prometheus 服务器可以处理的数量。

例如,您可能有一个 HTTP 服务器公开一个由 HTTP 方法分割的请求计数器:

http_requests_total{method="POST"}
http_requests_total{method="GET"}
http_requests_total{method="PUT"}
http_requests_total{method="DELETE"}

这完全没问题,只要您确保仅在method标签中存储有效的方法值即可。然而,也许现在您想到了通过请求用户的 ID 来有效地分割指标:

http_requests_total{method="POST",user_id="1"}
http_requests_total{method="POST",user_id="2"}
http_requests_total{method="POST",user_id="3"}
[…many more…]
http_requests_total{method="POST",user_id="16434313"}

http_requests_total{method="GET",user_id="1"}
http_requests_total{method="GET",user_id="2"}
http_requests_total{method="GET",user_id="3"}
[…many more…]
http_requests_total{method="GET",user_id="16434313"}
[…many more…]

假设您拥有多个用户,您现在将遭受基数爆炸,这将导致 Prometheus 服务器的内存使用量达到 OOM(内存不足)崩溃的程度。

因此请始终记住:指标上的每一个独特的标签组合都会自动创建一个时间序列,Prometheus 必须摄取、索引、存储和处理该时间序列。虽然对于可以放入单个标签中的值的数量没有绝对的硬性限制,但您需要保持在 Prometheus 服务器可以处理的时间序列的总预算之内。例如,大型 Prometheus 服务器可能能够处理多达几百万个时间序列,因此您需要选择标签的组合、它们所在的指标以及相应地公开这些指标的目标数量,以便您保持在该服务器的时间序列总预算范围内。

特别是,您需要避免存储无界的高基数值,例如:

  • 公共 IP 地址或电子邮件地址
  • 完整的 HTTP 路径,如果这些路径包含 ID 或其他无界基数信息
  • 进程 ID(除非严格限制到特定集合)

有时,您可以通过减少标签值的基数来解决标签的高基数问题,而无需完全删除它,同时仍然保留最有用的信息。例如,对于表单的 HTTP 路径/api/users/739567637385/posts/28388445,您至少可以用最终标签值中的占位符替换路径的最高基数组件(本例中的用户和帖子 ID),以生成更通用的模式,例如生成/api/users/{user_id}/posts/{post_id}方式更少的不同标签值和时间序列。

Mistake 2: Aggregating away valuable labels in alerting expressions

在编写聚合整个服务的警报表达式时,一个常见的诱惑是聚合掉您不需要立即需要的任何标签来确定是否存在问题。例如,如果您想确定服务的总体错误率(跨所有标签维度)是否太高,您可以编写如下规则:

sum(rate(errors_total{job="my-job"}[5m])) > 10

默认情况下,sum()聚合器生成不带任何标签的单个输出系列。这不仅会删除您实际想要聚合的维度(例如实例、错误类型等),还会删除所有输入系列中常见的所有标签,这些标签稍后可能对路由或消除警报有用。警报管理器。特别是job标签(或等效的服务分组标签)是常见的路由标签,因为作业通常与负责处理其警报的团队相关联。因此,建议尽可能在聚合中保留此标签:

sum by(job) (rate(errors_total{job="my-job"}[5m])) > 10

更好的选择是通过使用聚合修饰符将聚合修饰符替换为排除列表方法来保留您不想显式删除的任何标签:by()without()

sum without(instance, type) (rate(errors_total{job="my-job"}[5m])) > 10

这样,输入系列上您未明确聚合的任何标签仍可在 Alertmanager 中用于警报聚合和路由,以及帮助您了解警报的来源。

Mistake 3: Using unscoped, “naked” selectors

编写 PromQL 查询(尤其是警报!)时,您需要格外小心,仅从要为其编写查询的作业或服务中选择数据。多个不相关的服务可能会公开相同的指标名称,甚至可能具有完全不同的语义含义。即使您最初编写查询时情况并非如此,明天可能会出现指标名称冲突的新服务,从而完全破坏您的警报规则或仪表板。
为了避免意外提取不相关作业的数据的情况,请务必使用标签匹配器来确定选择器的范围,该标签匹配器明确命名您所引用的作业或服务。通常,这就是job标签。

例如,不安全的“裸”选择器可能会从您不期望的其他作业中选择具有相同指标名称的数据:

rate(errors_total[5m]) > 10

更安全的范围选择器会将所选指标限制为来自作业的指标my-job:

rate(errors_total{job="my-job"}[5m]) > 10

通过这种方式,您还可以避免出现以下情况:一旦刮掉另一个产生指标名称冲突的服务,您的警报规则或仪表板就会开始出现异常行为。

Mistake 4: No for duration in alerting rules

警报规则中的字段for允许您指定输出时间序列需要在连续的规则评估周期中存在多长时间才能从待处理警报转变为触发警报。这本质上允许您向警报规则添加每个系列的时间容差。现在您可能想知道哪些警报应该有for持续时间,以及应该持续多长时间。在大多数警报中完全省略持续时间可能是个好主意吗for?

考虑一个警报规则,该规则使用up指标来查找无法成功抓取的目标,并省略可选for修饰符:

alert: InstanceDown
expr: up == 0

一次失败的抓取(这很容易发生)将导致此规则触发。通常,您会希望让警报规则不那么容易触发,并在通知人员之前至少等待几分钟以查看问题是否仍然存在:

alert: InstanceDown
expr: up == 0
for: 5m  # An instance needs to be down / unreachable for 5 minutes before creating an alert for it.

对于已经内置了一些时间平均的警报表达式来说,不指定for持续时间甚至可能会出现问题。请考虑此警报的高错误率:

alert: HighErrorRate
expr: rate(my_errors_total{job="my-job"}[5m]) > 10

此规则将在第一次评估时触发,其中错误率较高( 5 分钟可用数据的平均值)。虽然 5 分钟平均值已经引入了一些鲁棒性,但请考虑当 Prometheus 服务器完全新鲜或一段时间没有收集数据时会发生什么:

  • 5 分钟rate()窗口将仅考虑一些最近的样本,而不是实际平均超过五分钟的数据。
  • 该规则现在可以为甚至还没有五分钟数据的系列立即生成警报。

引入for持续时间可以解决此问题:

alert: HighErrorRate
expr: rate(my_errors_total{job="my-job"}[5m]) > 10
for: 5m

对于大多数警报规则也可以提出类似的论点。因此,为了使您的警报规则更加强大,您几乎总是希望将for持续时间设置为至少几分钟。请记住,这也会导致警报反应时间变慢for,因此找到时间容差的平衡点很重要。

Mistake 5: Too short rate() windows

当在太短的时间窗口内计算速率时,您是否曾经因间隙或完全空的图表而感到沮丧,例如rate(my_counter[1m])?rate()和其他 PromQL 函数(如increase()、irate()、deriv())告诉您时间序列在给定时间窗口内上升或下降的速度,都需要在输入时间窗口下至少有两个样本才能告诉您该序列在之间的发展情况这两个样本。如果您将时间窗口设置得太小,则可能会面临窗口下只有 1 个或 0 个样本的风险,在这种情况下,输出将变为空。

例如,如果您采用rate()每 15 秒抓取一次的 20 秒范围内的计数器指标,则很有可能这 20 秒通常不会覆盖两个样本,因此您会得到一个间隙率:

【博客675】prometheus生产上易犯的错误
采取极端的方式:如果将速率窗口减少到 16 秒,当两个相隔 15 秒的点碰巧落在任意对齐的 16 秒窗口下时,您只会偶尔获得输出点:

【博客675】prometheus生产上易犯的错误
如果进一步减小窗口,您最终将根本没有机会覆盖两个样本,因此您会得到完全空的查询输出:

【博客675】prometheus生产上易犯的错误
因此,您需要选择足够大的输入窗口 - 不仅仅是 2 倍的抓取间隔,而且您还希望在面对偶尔的抓取失败和不幸的窗口对齐时保持稳健。通常,选择速率窗口大小至少为抓取间隔的 4 倍是一个好习惯:
【博客675】prometheus生产上易犯的错误

提示:使用Grafana时,您还可以使用$__rate_interval模板变量自动为您选择一个安全间隔。

Mistake 6: Using rate() and friends with the wrong metric type

虽然 PromQL 以其他一些方式进行静态类型化,但它无法直接告诉您是否将错误类型的指标传递到并非旨在处理该错误的函数中。最突出的例子是:

  • Using rate() with gauge metrics

    rate()、irate()和函数increase()被设计为仅与计数器度量一起使用。计数器是跟踪累积计数的指标,这些计数只会增加(而不会减少),除非0跟踪过程重新启动时偶尔重置。为了在速率计算中尽可能抵消计数器重置,这些函数尝试将提供的时间窗口下样本值的任何减少解释为重置并对其进行补偿(另请参阅我们有关速率计算的详细文章)。这种计数器重置检测和补偿意味着您只能0从这些功能中获得积极的结果(或 )。如果您不小心传递了一个可以自然上升的计量指标如果下降(如内存使用情况),PromQL 将无法分辨出此错误,而只会返回不正确的输出值。这是因为每次您的仪表指标下降时,rate()都会将其解释为计数器重置,并会错误地“纠正”它。

  • Using deriv() with counter metrics

    您可以将该deriv()函数视为大致相当于rate(),但对于仪表而言。deriv()告诉您在输入时间窗口内测量的仪表指标每秒上升或下降的速度。虽然不常见,但与rate()这里相同的陷阱可能会以另一种方式击中您:由于该deriv()函数没有实现有关计数器重置的任何逻辑(仪表没有这些!),尝试计算deriv()计数器指标将给出每当在提供的窗口下重置计数器时,您都会得到错误的结果,有时甚至是负面的结果。文章来源地址https://www.toymoban.com/news/detail-501932.html

到了这里,关于【博客675】prometheus生产上易犯的错误的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【博客654】prometheus配置抓取保护以防止压力过载

    担心您的应用程序指标可能突然激增,以及指标突然激增导致prometheus压力过载 就像生活中的许多事情一样,标签要有节制。当带有用户 ID 或电子邮件地址的标签被添加到指标时,虽然它不太可能结束,因为突然之间,您的一个目标可能会在每次抓取时抽出数十万个时间序列

    2024年02月09日
    浏览(47)
  • 【博客669】prometheus rate()选择range范围的最佳实践

    我们使用rate来计算counter的速率,那么rate的range范围应该选择哪一个?有没有固定的答案呢?30s,1m? 答案:没有,要根据你的scrap_interval来决定的 选择范围的一般规则是至少应为刮擦间隔的 4 倍。这是为了允许各种竞争条件,并对失败的刮擦具有弹性。 剖析: 假设您有一个

    2024年02月10日
    浏览(40)
  • 【博客671】prometheus如何选择数据点以及处理counter跳变

    时间是怎么进来的?范围和即时查询! 您可能已经注意到,PromQL 查询中对时间的唯一引用是相对引用(例如[5m],回顾 5 分钟)。那么如何指定绝对图形时间范围或在表中显示查询结果的时间戳呢?在 PromQL 中,此类时间参数与表达式分开发送到Prometheus 查询 API,确切的时间

    2024年02月11日
    浏览(53)
  • 【笔记】企业监控Prometheus和Grafana生产实战

    作者:林哥linux 来源:b 站  P1 1-1 prometheus 概述 P2 1-2 二进制安装prometheus P3 1-3 docker安装prometheus P4 1-4 prometheus相关概念 P5 2-1 什么是Exporter P6 2-2 监控linux服务器 P7 2-3 监控nginx P8 2-4 监控redis P9 2-5 监控rabbitmq P10 2-6 监控mongodb P11 27 监控docker P12 2-8 监控mysql8.0 P13 2-9 监控springboot2.

    2024年02月07日
    浏览(35)
  • 【博客655】prometheus如何应对告警目标消失带来的评估缺失问题

    基于拉取的监控(例如 Prometheus)的优势之一是,您可以在抓取过程中判断目标是否健康。 关于 Prometheus 的一个常见问题是如何判断服务器是否没有响应或检测样本是否不再从目标中摄取。简单黑盒监控的首选工具是黑盒导出器,您可以使用 unless 和 offset 进行边缘检测,以检

    2024年02月09日
    浏览(69)
  • 【博客647】MetricsQL(VictoriaMetrics)和PromQL(Prometheus)的不同之处

    https://valyala.medium.com/promql-tutorial-for-beginners-9ab455142085 2-1、MetricsQL 考虑了方括号中窗口之前的前一个点,用于范围函数,例如速率和增加。这允许返回用户对 increase(metric[$__interval]) 查询期望的准确结果,而不是 Prometheus 为此类查询返回的不完整结果 2-2、MetricsQL不推断范围函数

    2024年02月08日
    浏览(61)
  • 【博客662】prometheus对rule规则和alert规则作单元测试

    在实际生产中,对于rules和alerts的配置有时候出于某些特殊原因,无法进行模拟,这时候就需要我们对采集规则和告警规则进行单元测试,以确保正确性 example: 要测试此规则,您可以使用以下内容创建 test.yml: 进行测试: 测试结果: 分析一下测试文件: 这表示我们要加载

    2024年02月09日
    浏览(43)
  • 【博客673】Lookback delta, Staleness and NaN in Prometheus

    Lookbackdelta是可以修改的,默认是5分钟 当必须定义“最新”样本时,就会出现棘手的情况。Prometheus 没有样本之间固定间隔的概念,因此很难绝对地说给定series是否存在“当前”最新样本。如果series的最新样本已经有一周了,您可能不希望将其包含在当前时间戳的即时向量选

    2024年02月11日
    浏览(34)
  • 【博客685】prometheus 出现NaN场景以及如何去除干扰(Not a Number)

    场景: 一些监控系统使用 NaN 作为空值或缺失值,但在 Prometheus 中 NaN 只是另一个浮点值。Prometheus 表示缺失数据的方式是让数据缺失。Prometheus 支持所有 64 位浮点值,包括正无穷大、负无穷大和 NaN。 出现NaN的情况示例: 除以分母0 用作过时处理一部分的标记。 然而,这是一

    2024年02月14日
    浏览(36)
  • 快速解决 npm 安装 node-sass 速度慢/错误的问题(nexus私服问题见上一篇博客)

    这通常是因为 node-sass 包中包含有本地二进制文件( _binding.node ),而在某些情况下,下载过程可能会失败。 以下是一些可能的解决方法: 1. 使用淘宝镜像 你可以尝试使用淘宝的 cnpm 命令行工具,该工具使用淘宝的镜像源,可以解决部分下载问题。首先,安装 cnpm : 然后使

    2024年02月03日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包