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

news2024/11/8 19:36:42

警惕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 通过(通常)仅支持附加到任何现有系列的末尾来反映这一点。这意味着它会拒绝时间戳早于同一系列中最新样本的传入样本。当样本具有不同的样本值时,它还会拒绝与系列中最新样本具有相同时间戳的样本(否则,它们将被忽略)。

在这里插入图片描述

但是,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:

在这里插入图片描述
这种行为通常没有有效的用例,但 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将向您显示相应的错误:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/683668.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023最全 Java 高频面试合集,掌握这些你也能进大厂

进大厂是大部分程序员的梦想,而进大厂的门槛也是比较高的,所以这里整理了一份阿里、美团、滴滴、头条等大厂面试大全,对于 Java 后端的朋友来说应该是最全面最完整的面试备战仓库,为了更好地整理每个模块,我也参考了很…

内网隧道代理技术(六)之 PowerCat反弹Shell

PowerCat反弹Shell PowerCat介绍 PowerCat是一个powershell写的tcp/ip瑞士军刀,看一看成ncat的powershell的实现,然后里面也加入了众多好用的功能,如文件上传,smb协议支持,中继模式,生成payload&#xff…

几分钟带你快速了解SpringBoot框架理论知识!

1.什么是SpringBoot SpringBoot其实就是Spring的子项目。它简化了Spring的开发难度,舍弃了一切可以舍弃的xml配置文件,提供了各种启动器,让程序员上手更快,节省了开发时间。 2.SpringBoot的优点 SpringBoot其实就是对Spring的缺…

抖音林客系统定制开发

抖音林客是一款提供旅游攻略和景点推荐的短视频社交平台,主要用户群体为喜欢旅游和分享生活的年轻人。从需求分析角度来看,可以从以下几个方面进行分析: 信息获取需求:抖音林客用户需求获取有关旅游的详细和实用的信息&#x…

Idea快捷键设置(Idea快捷键大全)

目录 友情提醒第一章、IDEA常用快捷键1.1)快捷键:查找/提示类1.2)快捷键:修改代码类1.3)快捷键:光标移动类 第二章、如何修改快捷键2.1)修改快捷键的方法2.2)我修改的快捷键&#xf…

不容错过!科东软件在2023华南国际工博会等你,一起见证科技的力量!

诚挚邀请 2023年6月27-29日,SCIIF华南国际工业博览会即将在深圳国际会展中心(宝安新馆)召开。本届华南工博会汇集大批国内外头部大咖,将呈现一系列世界领先的技术和创新理念,为新型工业发展注入新动力。 科东软件作为…

华为eNSP入门实验,Vlan配置,路由配置,用户模式,链路聚合

文章目录 一、同一交换机下的PC通信二、不交换机下的PC通信三、配置静态路由通信四、路由器rip协议配置五、路由器ospf协议配置六、单臂路由七、通过三层交换机使不同的Vlan能连通八、设备consolo密码模式九、设备consolo用户密码模式(AAA模式)十、Telne…

2023年低代码平台全球排行榜:企业首选榜单,揭晓最受欢迎的工具

近年来,随着数字化转型和云计算技术的普及,低代码平台已经成为企业开发和应用程序的首选工具之一。低代码平台可以大大缩短开发时间和成本,提高灵活性和可扩展性,同时保证应用程序的质量和稳定性。在这个强制数字化的时代&#xf…

关于npm和package.json的一些经验之谈(如何同时使用多个版本的echarts)

前言 人们往往会忽视他们最常用的东西的一些构造原理,感觉就是天生自带没有为什么。但是真的被问到这些问题的时候,却又答不上来。对于前端开发工程师来说,npm和package.json就是这样的东西。很熟悉却又很陌生。熟悉,是因为&…

【消费战略方法论】食品品牌成功的本质

消费始于消费者 也终于消费者 当下的品牌是否都是以“消费者”为核心进行打造和运营的?面对着越来越多、五花八门的战略思路、品牌方法、营销理论,很多品牌越来越偏离了“消费”的本质。沉迷于精湛的营销打法之前是否需要先审视一下做品牌的初衷。 现…

Nginx服务性能和安全优化

目录 一、配置Nginx隐藏版本相关信息 1.隐藏版本号 2.修改版本号及相关信息 ​编辑​编辑 二、修改Nginx运行时的属主和属组 三、配置Nginx网页缓存时间 四、配置Nginx站点日志分割 五、设置Nginx长连接及超时时间 六、配置Nginx网页压缩 七、配置Nginx防盗链 1.模拟…

人工智能-A*启发式搜索算法解决八数码问题 Python实现

一.问题描述 八数码问题也称为九宫问题。在 33 的棋盘,摆有八个棋子,每个棋子上标有 1 至 8 的某一数字,不同棋子上标的数字不相同。棋盘上还有一个空格(以数字 0 来表示),与空 格相邻的棋子可以移到空格中…

操作系统——Linux 进程间通信

一:实验题目 Linux 进程间通信 二:实验目的 Linux 系统的进程通信机构(IPC)允许在任意进程间大批量地交换数据,通过本实验,理解 熟悉 Linux 支持的消息通信机制。 三:实验内容(…

企业级微服务架构实战项目--xx优选-小程序安装篇4

一 搭建微信小程序前端环境 1.1 申请小程序测试号 申请地址:微信公众平台 使用微信扫描二维码进行申请,申请成功之后,进入界面,获取小程序ID和秘钥 。 AppID(小程序ID) wx62bfe844fea3eba8 AppSecret(小程序密钥) …

JavaScript ES9新特性

文章目录 Object spread syntax(对象扩展语法)Promise.prototype.finally()Asynchronous Iteration(异步迭代):Rest/Spread Properties(剩余和扩展属性):RegExp named capture group…

Apikit 自学日记:导入、导出文档

一、导入API文档 功能入口:API管理应用 / 选中某个项目 / API文档菜单 / 点击“ API”按钮旁的下拉按钮 / 选中“导入API” Eolink提供一键导入已有API文档的功能,支持多种产品格式。常用于新项目创建后,需要对旧项目或旧软件内数据进行迁移…

认识设计组件帮助测试,以提高产品用户体验

一、控制元素 1、活动指示器——应与背景想协调,用于持续时间不明的进程,单一元素不显示,大于1个显示 2、加载控件——同一个专区页面,加载样式统一 3、页码控制器——原点最好控制在5点内,左右滑动,点击原…

OpenCL编程指南-5.5图像读、写函数

读图像 OpenCL GPU设备有专用硬件来读、写图像。OpenCL C图像读、写函数允许开发人员充分利用这个专用硬件。OpenCL 中的图像支持是可选的。要了解一个设备是否支持图像,可以使用clGetDeviceInfo API查询CL_DEVICE_IMAGE_SUPPORT属性。 需要说明的是&#xff0…

c4d+AI+PS设计广告展示架/销售柜台/展示盒子的建议

1、首先做出我标识出来的样子,这里称作A面。(可用软件:PS、AI、cdr等) 2、制作用于展示盒A面PNG图片(PS来掏空空白处用于描边)。 操作:按需求缩小图片,载入选区,新建图层…

three.js标准网格材质(MeshStandardMaterial)光照、粗糙度、金属度、法线属性介绍

如上图,在前面的章节中我们通过设置物体的纹理和材质实现了一个3d的立体门框的效果 完整代码如下: import * as THREE from "three"; // 导入轨道控制器 import { OrbitControls } from "three/examples/jsm/controls/OrbitControls&quo…