【博客674】警惕Prometheus 中的重复样本和无序时间戳错误

这篇具有很好参考价值的文章主要介绍了【博客674】警惕Prometheus 中的重复样本和无序时间戳错误。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

警惕Prometheus 中的重复样本和无序时间戳错误

1、场景

您的 Prometheus 服务器日志中是否遇到过以下错误?

"Error on ingesting out-of-order samples"
"Error on ingesting samples with different value but same timestamp"
"duplicate sample for timestamp"

那么您的设置中可能存在配置错误,导致多个系列相互碰撞和冲突。在这篇文章中,我们将解释这些错误背后的背景、可能导致这些错误的原因以及如何调试和修复它们。

2、背景:TSDB(通常)仅追加

Prometheus 是一个实时监控系统,通常只需要随着时间的推移以稳定持续的方式跟踪指标。Prometheus TSDB 通过(通常)仅支持附加到任何现有系列的末尾来反映这一点。这意味着它会拒绝时间戳早于同一系列中最新样本的传入样本。当样本具有不同的样本值时,它还会拒绝与系列中最新样本具有相同时间戳的样本(否则,它们将被忽略)。

【博客674】警惕Prometheus 中的重复样本和无序时间戳错误

但是,Prometheus 可能会出现错误配置,导致 Prometheus 尝试附加到 TSDB 时获得重复或无序的样本时间戳,但未能成功。这通常是由于多个时间序列之间的意外标签集冲突导致序列看起来相同(相同的指标名称和标签集),但也可能有其他原因。发生这种情况时,向 TSDB 追加违规样本将失败,Prometheus 将记录相应的错误。

注意: Prometheus 2.39引入了一项实验性out_of_order_time_window配置设置,允许在有限的时间内摄取无序样本,但默认情况下不启用此功能。在某些无法实时收集所有数据的情况下,它可能很有用。

3、样本时间戳错误的根本原因

3-1、重复目标:

在正确配置的 Prometheus 设置中,每个目标都有自己独特的目标标签集。Prometheus 将这些标签附加到从目标提取的所有系列,以帮助消除来自不同目标的相同指标的歧义。但 Prometheus 可能会出现错误配置,导致多个目标共享相同的标签集,这可能会导致结果时间序列之间的标签集冲突。然后,TSDB 会将多个原始系列的流视为单个系列,但当它们的样本因无序或重复时间戳而相互冲突时,会拒绝无效追加。

这是一种轻松引发这种重复的方法,通过将目标组的标签显式设置job为与您的 中具有相同目标的另一个作业相同的值prometheus.yml:

global:
  scrape_interval: 5s

scrape_configs:
- job_name: demo
  static_configs:
  - targets:
    - demo.promlabs.com:10000
- job_name: demo2
  static_configs:
  - labels:
      # Override the "job" label to also be "demo" instead of "demo2".
      job: demo
    targets:
    - demo.promlabs.com:10000

job上述的另一种变体可以通过将目标重新标记规则添加到第二个抓取配置并以此方式覆盖标签来实现"demo"。
当其中一个重复目标在另一个目标之前开始抓取,但最后完成抓取时,您将收到一条"Error on ingesting out-of-order samples"错误消息,因为第一个目标尝试将其样本插入到 TSDB 中,其抓取时间戳早于第二个已完成的目标。作为完整的日志行,它看起来像这样:

ts=2022-12-14T12:21:05.833Z caller=scrape.go:1681 level=warn component="scrape manager" scrape_pool=demo target=http://demo.promlabs.com:10000/metrics msg="Error on ingesting out-of-order samples" num_dropped=254

当两个重复的目标在完全相同的毫秒开始抓取时(这可能并且确实发生在来自不同抓取池的目标之间),它们将尝试使用相同的抓取时间戳存储其结果样本。但其中一个附加操作将失败并显示"Error on ingesting samples with different value but same timestamp"错误消息:

ts=2022-12-14T12:18:10.841Z caller=scrape.go:1684 level=warn component="scrape manager" scrape_pool=demo target=http://demo.promlabs.com:10000/metrics msg="Error on ingesting samples with different value but same timestamp" num_dropped=58

通常,错误消息中的scrape_pool和字段应该足以将您指向配置文件中的正确位置,以查找并修复冲突的目标。target但是,如果远程服务发现机制产生重复的目标,或者服务发现源和目标重新标记规则之间存在交互,导致消除歧义的标签丢失,则重复在配置文件本身中可能不可见。在这种情况下,您可能还需要查看/targetsPrometheus 服务器的页面,以发现多个抓取池或抓取配置之间具有相同标记的目标(同一个抓取池中不可能有相同的目标,因为 Prometheus 会自动对它们进行重复数据删除)成一个)。这/service-discovery页面还显示所有发现的目标及其重新标记前后的标签集。要修复摄取错误,请确保所有目标都有唯一的标签。

3-2、有问题的客户端时间戳:

通常,Prometheus/metrics端点不会包含它们公开的样本的显式时间戳。相反,Prometheus 为所有提取的样本分配自己的抓取开始时间戳。但是,也可以以Prometheus 指标说明格式为样本提供显式的客户端时间戳。例如,如果您想要公开一个test_metric值为42且毫秒 Unix 时间戳为 的指标1671021749332,则公开格式将如下所示:

# HELP foo A test metric with an explicit timestamp.
# TYPE foo gauge
test_metric 42 1671021749332

鉴于最初提到的 TSDB 限制,如果该功能被滥用或错误实现,这里可能会出现很多问题:如果客户端时间戳在两次抓取之间向后移动,您将收到无序错误。如果它保持不变,但样本值发生变化,您将收到重复时间戳错误。
这种情况下的错误消息看起来与重复目标的错误消息类似,因为它们都源自抓取层。然而,错误日志中的简单目标信息可能不足以在损坏的目标中找到特定的有问题的指标。幸运的是,在 Prometheus 服务器上设置该–log.level=debug标志会增加日志记录的详细程度,以便您可以看到series导致问题的每个系列(在日志消息字段中)。

对于重复的时间戳,将如下所示:

ts=2022-12-14T10:23:40.297Z caller=scrape.go:1730 level=debug component="scrape manager" scrape_pool=prometheus_dupe target=http://demo.promlabs.com:10000/metrics msg="Duplicate sample for timestamp" series=go_goroutines

对于无序时间戳,如下所示:

ts=2022-12-14T13:12:45.844Z caller=scrape.go:1725 level=debug component="scrape manager" scrape_pool=demo target=http://demo.promlabs.com:10000/metrics msg="Out of order sample" series=go_goroutines

在这种情况下,您必须修复损坏目标中的指标说明才能解决问题。

3-3、规则中的重复系列:

还可以在多个记录规则的输出之间创建冲突系列。colliding_name以此规则文件为例,它记录同一规则组中两个规则的指标,但具有不同的样本值:

groups:
- name: dupe
  rules:
  - record: colliding_name
    expr: 0
  - record: colliding_name
    expr: 1

尽管同一组中的多个规则的评估是按顺序发生的,但 Prometheus 将以相同的查询评估时间戳运行所有规则。这会导致规则评估失败并出现"duplicate sample for timestamp"错误:

ts=2022-12-15T10:07:25.976Z caller=manager.go:684 level=warn component="rule manager" file=dupes-rules.yml group=dupe name=colliding_name index=1 msg="Rule evaluation result discarded" err="duplicate sample for timestamp" sample="{__name__=\"colliding_name\"} => 1 @[1671098845972]"

此错误还有助于记录规则组、记录的指标名称以及示例的违规标签集。这样,您应该能够修复规则文件中的问题。
作为一种变型,这种冲突也可能发生在由记录规则产生的系列与目标刮擦之间。

3-4、远程写入发送错误数据:

如果您使用Prometheus 服务器自己的远程写入接收器将样本推送到 Prometheus,您还可能会遇到一个或多个推送源发送冲突的指标和时间戳的情况。在这种情况下,您可能会在发送端收到"Out of order sample from remote write"或请求错误:“duplicate sample for timestamp”

ts=2022-12-15T10:49:51.792Z caller=dedupe.go:112 component=remote level=error remote_name=45e379 url=http://localhost:9090/api/v1/write msg="non-recoverable error" count=6 exemplarCount=0 err="server returned HTTP status 400 Bad Request: out of order sample"

或者:

ts=2022-12-15T10:51:31.437Z caller=dedupe.go:112 component=remote level=error remote_name=45e379 url=http://localhost:9090/api/v1/write msg="non-recoverable error" count=3 exemplarCount=0 err="server returned HTTP status 400 Bad Request: duplicate sample for timestamp"

在接收 Prometheus 服务器中,您将收到类似的错误消息(一旦修复了我们在撰写本文过程中发现的错误):

ts=2022-12-15T11:04:23.006Z caller=write_handler.go:107 level=error component=web msg="Out of order sample from remote write" err="out of order sample" series="{__name__=\"foo\", instance=\"localhost:8080\", job=\"remote\"}" timestamp=1671102261810

后一条消息告诉您确切的违规系列,因此您有望找到并修复其来源。

3-5、故意摄取无序数据:

现在,有一些有效的用例,您可能实际上想要提取无序数据,甚至是通常太旧而根本无法提取到 TSDB 中的数据。您可能有一些数据源无法持续生成指标,而只能提供批量或延迟的结果。对于这些情况,如上所述,您需要打开 Prometheus 新的实验性out_of_order_time_windowTSDB 配置设置,该设置允许在有限的时间内摄取无序样本,以消除这些错误消息。

注意:并非所有碰撞都会导致错误!

正如我们上面刚刚了解到的,Prometheus 可以注意到并告诉我们多种系列碰撞条件。但在某些情况下,普罗米修斯会默默地忽略一系列碰撞,或者根本无法检测到它们。因此,没有看到错误并不能保证一切正常。

3-6、度量重新标记导致的冲突静默失败:

其中一种情况是,意外地使用度量重新标记(在抓取过程中应用于每个拉取的系列)从单个目标中删除重要的系列消除歧义标签。例如,以下配置quantile从所有拉取的指标中删除标签,但在go_gc_duration_seconds指标中,需要此标签来区分 3 个不同的系列:

global:
  scrape_interval: 5s
    
scrape_configs:
- job_name: prometheus
  static_configs:
  - targets:
    - localhost:9090
  metric_relabel_configs:
  - action: labeldrop
    target_label: quantile

Prometheus 当前的行为是存储第一个冲突样本,但在没有任何警告的情况下默默地丢弃后续样本。

3-7、两个规则或目标写入同一个系列,没有时间冲突:

很容易发生这样的情况:Prometheus 要么抓取两个重复的目标,要么从写入同一序列的两个规则中获取样本,但样本总是以完美的同步方式到达,而不会创建无序条件或重复的时间戳。在这种情况下,来自两个源的样本将被写入相同的时间序列,并且相同的值在两个输入序列之间来回变化。

colliding_name例如,如果您创建了这样的规则文件,则使用样本值0和来记录指标1:

groups:
- name: collision 
  rules: 
  - record: colliding_name  
    expr: 0
- name: collision2                                                                                                                       
  rules:                                                                                                                                
  - record: colliding_name                                                                                                              
    expr: 1

那么您可能不会看到任何记录的错误(除非两个规则组碰巧以完全相同的重复时间戳运行)。但是,您将看到该系列的样本值在0和之间交替1:

【博客674】警惕Prometheus 中的重复样本和无序时间戳错误
这种行为通常没有有效的用例,但 Prometheus 目前无法自动检测这种情况。

4、使用指标检测这些问题

除了读取记录的错误消息之外,您还可以通过监控 Prometheus 公开的以下指标来检测无序和重复的时间戳:

  • prometheus_tsdb_out_of_order_samples_total:由于禁用乱序支持而导致尝试提取失败的乱序样本总数。
  • prometheus_target_scrapes_sample_duplicate_timestamp_total:具有重复时间戳的抓取样本总数。
  • prometheus_target_scrapes_sample_out_of_order_total:抓取的乱序样本总数。
  • prometheus_http_requests_total{code=“400”,handler=“/api/v1/write”}400:远程写入接收器(在接收 Prometheus 服务器中)收到的状态码请求总数。400这也可能包括导致 a 的错误。
  • prometheus_remote_storage_samples_failed_total:发送 Prometheus 服务器中通过远程写入发送失败的样本总数。这还可能包括其他错误。

不幸的是,规则评估中的系列冲突错误尚未显示在指标中。有一个prometheus_rule_evaluation_failures_total指标,但仅计算规则评估的总失败次数,而不计算评估期间丢弃的单个系列。然而,有问题的输出系列的规则仍将被标记为不健康,并且页面/rules将向您显示相应的错误:

【博客674】警惕Prometheus 中的重复样本和无序时间戳错误文章来源地址https://www.toymoban.com/news/detail-500530.html

到了这里,关于【博客674】警惕Prometheus 中的重复样本和无序时间戳错误的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

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

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

    2024年02月11日
    浏览(41)
  • 警惕百度中的木马程序,受害企业数持续上升

    近日,有研究机构发现,名为“谷堕大盗”的黑客正利用百度中的搜索结果,大规模传播木马程序,伪装度和隐蔽程度较高,受害企业呈持续上升趋势。 调查发现,该黑客团伙针对金融、制造等行业进行的大规模钓鱼攻击活动,通过追溯后门程序来源,确认本次样本为通过搜

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

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

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

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

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

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

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

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

    2024年02月09日
    浏览(33)
  • 【博客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日
    浏览(42)
  • 【博客673】Lookback delta, Staleness and NaN in Prometheus

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

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

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

    2024年02月14日
    浏览(28)
  • Prometheus-08 安装配置prometheus时的ntp时间同步问题

    prometheus需要本地时间与容器时间一致,首先检查本地时间,输入date查看本地时间,设置本地主机的时区和时间 查看时区 在输出结果中,找到 “Time zone” 行,确认当前的时区设置。 centos安装ntp 1:手动同步NT

    2024年02月16日
    浏览(28)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包