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

在这里插入图片描述

但是,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将向您显示相应的错误:

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

图解CNN中的卷积(卷积运算、池化、Padding、多通道的卷积)

文章目录 卷积操作池化Padding对多通道(channels)图片的卷积套上激活函数是什么样的参考: 卷积层是深度学习神经网络中经常使用的一种层。它通过卷积运算来提取输入的特征,常用于图像、语音等信号处理任务中。 卷积层有以下几个参…

探索iOS之Metal编程指南

iOS推出Metal渲染库为了取代OpenGL。Metal有自己的Shader语言,渲染效率比OpenGL高。在这里我们一起探索:Metal使用C限制、预处理定义、动态链接配置、GPU编译配置、设备坐标系、视口坐标系、纹理坐标系、矢量类型、矩阵类型、采样器状态、矩阵相乘。 1、…

第 107 场LeetCode双周赛

A 最大字符串配对数目 显然各字符串对 间匹配的先后顺序不影响最大匹配数目, 可以从后往前遍历数组, 判断前面是否有和当前末尾构成匹配的. class Solution { public:int maximumNumberOfStringPairs(vector<string> &words) {int res 0; while (words.size…

使用 Jetpack Compose 构建 RadioButton

欢迎阅读本篇关于使用 Jetpack Compose 构建 RadioButton&#xff08;单选按钮&#xff09;的博客。Jetpack Compose 是 Google 发布的现代化 UI 工具包&#xff0c;用于构建 Android 界面。它的声明式设计使得 UI 开发更加简洁直观。 一、什么是 RadioButton&#xff1f; Rad…

【深度学习】3-4 神经网络的学习- 学习算法的实现

神经网络的学习步骤如下所示&#xff1a; 步骤1(mini-batch) 从训练数据中随机选出一部分数据&#xff0c;目标是减小mini-batch的损失函数的值 步骤2(计算梯度) 为了减小mini-batch的损失函数的值&#xff0c;需要求出各个权重参数的梯度 步骤3(更新参数) 将权重参数沿梯度…

ModaHub魔搭社区:向量数据库MIlvus服务端配置(四)

目录 常见问题 常见问题 除了配置文件外&#xff0c;怎样可以判断我确实在使用 GPU 做搜索&#xff1f; 有以下三种方式&#xff1a; 使用 nvidia-smi 命令查看 GPU 使用情况。用 Prometheus 配置&#xff0c;详见 使用 Grafana 展示监控指标 > 系统运行指标。使用 Milv…

【完美复现】面向配电网韧性提升的移动储能预布局与动态调度策略【IEEE33节点】(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

制造企业实施MES系统受到的影响因素有哪些?

实施MES系统会遇到哪些影响因素&#xff1f;或者说企业实施MES系统的交付率为什么低&#xff1f; 我觉得关键点在于&#xff1a;在当前MES产品化程度普遍不高的大环境下&#xff0c;对项目及管理软件本身认知过于简单&#xff0c;且缺失有经验行业人才&#xff0c;是当前大部分…

windows下安装Visual Studio + CMake+OpenCV + OpenCV contrib+TensorRT

目录 1 安装visual studio 2 安装CMake 3 OpenCV源码安装 3.1 OpenCV源码下载 3.2 OpenCV contrib源码下载 3.3 安装OpenCV 3.4 安装OpenCV-crontrib 3.5 VS生成代码 4 环境配置 5 TensorRT安装 5.1 TensorRT安装 5.2 Python下安装TensorRT库 最近在研究windows系统…

Unity渲染工程收集

NPR 非真实渲染 UnityURP-AnimeStyleCelShader SSR 屏幕空间反射 UnitySSReflectionURP

分布式机器学习(Parameter Server)

分布式机器学习中&#xff0c;参数服务器(Parameter Server)用于管理和共享模型参数&#xff0c;其基本思想是将模型参数存储在一个或多个中央服务器上&#xff0c;并通过网络将这些参数共享给参与训练的各个计算节点。每个计算节点可以从参数服务器中获取当前模型参数&#xf…

架构基本概念和架构本质

什么是架构和架构本质 在软件行业&#xff0c;对于什么是架构&#xff0c;都有很多的争论&#xff0c;每个人都有自己的理解。此君说的架构和彼君理解的架构未必是一回事。因此我们在讨论架构之前&#xff0c;我们先讨论架构的概念定义&#xff0c;概念是人认识这个世界的基础…

UWB超宽带定位技术的原理及定位方法

uwb定位技术即超宽带技术&#xff0c;它是一种无载波通信技术&#xff0c;利用纳秒级的非正弦波窄脉冲传输数据&#xff0c;因此其所占的频谱范围很宽。传统的定位技术是根据信号强弱来判别物体位置&#xff0c;信号强弱受外界 影响较大&#xff0c;因此定位出的物体位置与实际…

Redis入门(4)-list

redis中list数据会按照插入顺序进行排序&#xff0c;其底层是一个无头结点的双向链表&#xff0c;因此表头和表尾的操作性能较高&#xff0c;但中间元素操作性能较差。 1.lpush key element [element ] 从表头插入元素 lpush nosql redis hbase lpush nosql mongdb2.lrange…

数据结构--单链表的插入删除

数据结构–单链表的插入&删除 目标 单链表的插入&#xff08;位插、前插、后插&#xff09; 单链表的删除 单链表的插入 按为序插入(带头结点) ListInsert(&L,i,e):插入操作。在表L中的第i个位置上插入指定元素e。 思路&#xff1a;找到第i-1个结点,将新结点插入其…

Mysql架构篇--Mysql(M-M) 主从同步

文章目录 前言一、M-M 介绍&#xff1a;二、M-M 搭建&#xff1a;1.Master1&#xff1a;1.1 my.cnf 参数配置&#xff1a;1.2 创建主从同步用户&#xff1a;1.3 开启复制&#xff1a; 2.Master2&#xff1a;2.1 my.cnf 参数配置&#xff1a;2.2 创建主从同步用户&#xff1a;2.…

Android12之ServiceManager::addService注册服务的本质(一百五十八)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药. 更多原创,欢迎关注:Android…

iOS多语言解决方案全面指南

本文以及相关工具和代码旨在为已上线的iOS项目提供一种快速支持多语言的解决方案。由于文案显示是通过hook实现的&#xff0c;因此对App的性能有一定影响&#xff1b;除了特殊场景的文案显示需要手动支持外&#xff0c;其他任务均已实现自动化。 本文中的部分脚本代码基于 Chat…

【软件设计师暴击考点】网络安全等杂项高频考点暴击系列

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;软件…

SpringBoot 日志文件:日志的作用?为什么要写日志?

文章目录 &#x1f387;前言1.日志长什么样子&#xff1f;2.自定义打印日志2.1 在程序中得到日志对象2.2 使用日志对象打印日志 3.日志级别3.1 日志级别的分类与使用3.2 日志级别有什么用呢&#xff1f;3.3 日志级别的设置 4.日志持久化保存5.更方便的日志输出5.1 添加 lombok …