热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

go实现重新给metric打标签上传到prometheus_案例分析|云原生监控Prometheus对样本rate计算,出现标签重复?...

0-本案例所涉及的知识点云原生、微服务,带你了解大规模容器下的监控方式,通过各个案例分析,熟悉prometheus的内部原理。涉及知识点&
60abb3c37bba94be3ba526a5e11c2a47.png

0 - 本案例所涉及的知识点

云原生、微服务,带你了解大规模容器下的监控方式,通过各个案例分析,熟悉prometheus的内部原理。

涉及知识点:go prometheus

1 - 案例概要

收到用户反馈,使用grafana通过设置prometheus数据源,绘制容器的网络指标时,出现异常,guan j z

647a0a0eb316dced3eb9c811ec0ecfe0.png

2 - 故障重现

服务端prometheus版本为2.9.2,通过访问内置UI地址 prometheus-server:9090,查询数据重现故障,错误截图如下,

7c790471781e815e6723c51a011042cb.png

通过浏览器开发者模式,获取当前具体的请求接口可表示为:

a4aac2f4e447e623ec111779aa87bec9.png

响应的HTTP状态码422 Unprocessable Entity,错误信息:

3afdc61de96aa99f621fb951ec38f9bc.png

3 - 初步假设

看字面意思是查询返回的样本结果集合中存在相同的标签,至于是什么标签相同,只能通过查询源码定位问题了。

4 - 理论知识

4.1 - Prometheus基础数据结构

首先熟悉Prometheus几个基础数据结构

719fd9cdaa5bedd2343a0e904e018c49.png

Sample与Series的区别:

  • Sample是样本:一个标签组合,只包含一个时间点以及该点的时间数据
  • Series是序列:一个标签组合,由多个时间点以及对应的数据组合而成

Vector与Matrix的区别:

  • Vector是一个向量数据结构,由多个样本组成,这些样本以时间为方向,具有相同的方向
  • Matrix是一个矩阵数据结构,由多个序列数据组成

4.2 - 通过关键字匹配定位源码

  • 异常关键字出现的代码位置

源码文件:github.com/prometheus/prometheus/promql/engine.go

fe74340b57d4dad81b7a74356b213262.png
69da590e0e0bc79ba917653225145003.png
  • 关键函数result.ContainsSameLabelset的实现源码

该函数主要用于检测在查询返回的数据中,是否存在相同的标签集合,由于向量与矩阵标签类型相同,所以实际它们内部的实现也是一样的。

源码文件:github.com/prometheus/prometheus/promql/value.go

5acf831f558fbc0f8b846b9bd184eea3.png
  • 判断样本标签组唯一性,函数s.Metric.Hash()的实现

源码文件:github.com/prometheus/prometheus/pkg/labels/labels.go

d609e3547e853503a25ba5a93e21f014.png

也就是在这计算中Vector(向量)或Matrix(矩阵),不能存在相同的Labels(标签组)。

5 - 疑点提出

  1. Prometheus的持久存储方案是内部开发团队自实现的,是这个引起的?
  2. Prometheus本地存储设置只保留最近24h的数据,难道是这部分数据异常?
  3. 分别关闭本地与远程存储,如果均正常,难道是查询返回了相同的两条指标?
  4. 向量与矩阵里面的样本或序列数据是不能存在相同的标签组合?

6 - 实践检验

6.1 - 实验前准备

下载源码,通过以下命令可编译二进制可执行文件

cd github.com/prometheus/prometheusgo build cmd/prometheus/main.go

6.2 - 验证疑点1

由于prometheus本身不适合做长久数据存储,所以我们内部设计了一套持久存储的方案,结合配置remote_read、remote_write实现。

为了验证疑点1,可以先把prometheus.yml中的remote_read设置关闭,然后重载prometheus配置。

a985b1eb65998f5ca1a7701eae4ec0a7.png
989b319a449b0de3287a7824e36aa861.png

通过停止remote_read设置之后就可以正常使用了,但这里也并不能确定就是设置remote_read的问题。

6.2 - 验证疑点2

通过关闭远程数据读取可以解决问题,那通过删除本地数据呢?通过以下步骤:

  1. 设置prometheus.yml取消原先对remote_read的注释。
  2. 关闭prometehus进程,清除本地存储目录下的所有数据,实际由storage.tsdb.path设置,如:data/*
  3. 重新启动prometheus进程。

在刚启动时候,可以正常查询出数据:

61d1474dbf35652b895e9c1e078887dc.png

等待一会后,出现同样问题:

b90a5c1982785fad659ef7cc9a2f4b6e.png

6.3 - 验证疑点3

在同时开启本地与远程数据存储的情况下,通过promQL查询以下语句:

container_network_receive_bytes_total{pod_name="magick-img-converter-747d899b66-lsrn6"}[1m]

接口返回内容:

1de79c374d01e21440d87b9fa0666e79.png

确实是访问两个相同标签组的数据,但是时间不同。

对这结果集使用rate函数计算,也就出现了原先的问题。

rate(container_network_receive_bytes_total{pod_name="magick-img-converter-747d899b66-lsrn6"}[1m])

6.4 - 验证疑点4

相同的标签组合是指:一组同样的标签名与标签值。这里通过更改prometheus代码,植入测试语句,获取从远程或本地的数据,对比差异,查询到底哪里导致这个问题的产生。

由以上几个疑点验证可知,问题出现在eval函数的case *Call语句中。

8a3af47095b5fc22c5d6d0dea1f64daa.png

通过对以上函数添加调试代码,然后编译promethues运行,在执行相应的promQL查询。

26cd9e7035ca1b347f911335d2784062.png
bfa55704deb1b541cfdeac3cb73d75bd.png

这里可以看到,存在两个数据,在未移除标签__name__之前,上图存在两个__name__,下图只有一个__name__,当移除之后,他们就存在相同的标签组了。

7 - 问题定位

查询指标数据时,prometheus分别从本地存储与远程存储获取数据,然后进行合并,远程存储获取的数据相比本地多了一个__name__标签。

8 - 解决方案

8.1 - 方案1

修复远程存储返回多余的__name__标签。

8.2 - 方案2

修改prometheus代码,如果存在重复的__name__标签键值,则想办法去重。

9 - 总结讨论

通过方案1,我们就解决了这个问题,同时也继续跟踪prometheus源码,能否为它提交PR,增强健壮性。

如存在疑问点,欢迎留言讨论,本人关注云原生生态,如果您也喜欢,欢迎关注我,一起学习,共同进步。



推荐阅读
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • Gitlab接入公司内部单点登录的安装和配置教程
    本文介绍了如何将公司内部的Gitlab系统接入单点登录服务,并提供了安装和配置的详细教程。通过使用oauth2协议,将原有的各子系统的独立登录统一迁移至单点登录。文章包括Gitlab的安装环境、版本号、编辑配置文件的步骤,并解决了在迁移过程中可能遇到的问题。 ... [详细]
  • 本文探讨了容器技术在安全方面面临的挑战,并提出了相应的解决方案。多租户保护、用户访问控制、中毒的镜像、验证和加密、容器守护以及容器监控都是容器技术中需要关注的安全问题。通过在虚拟机中运行容器、限制特权升级、使用受信任的镜像库、进行验证和加密、限制容器守护进程的访问以及监控容器栈,可以提高容器技术的安全性。未来,随着容器技术的发展,还需解决诸如硬件支持、软件定义基础设施集成等挑战。 ... [详细]
  • [echarts] 同指标对比柱状图相关的知识介绍及应用示例
    本文由编程笔记小编为大家整理,主要介绍了echarts同指标对比柱状图相关的知识,包括对比课程通过率最高的8个课程和最低的8个课程以及全校的平均通过率。文章提供了一个应用示例,展示了如何使用echarts制作同指标对比柱状图,并对代码进行了详细解释和说明。该示例可以帮助读者更好地理解和应用echarts。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文介绍了Linux系统中正则表达式的基础知识,包括正则表达式的简介、字符分类、普通字符和元字符的区别,以及在学习过程中需要注意的事项。同时提醒读者要注意正则表达式与通配符的区别,并给出了使用正则表达式时的一些建议。本文适合初学者了解Linux系统中的正则表达式,并提供了学习的参考资料。 ... [详细]
  • Ubuntu 9.04中安装谷歌Chromium浏览器及使用体验[图文]
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 本文介绍了在Mac上安装Xamarin并使用Windows上的VS开发iOS app的方法,包括所需的安装环境和软件,以及使用Xamarin.iOS进行开发的步骤。通过这种方法,即使没有Mac或者安装苹果系统,程序员们也能轻松开发iOS app。 ... [详细]
  • 本文介绍了使用Spark实现低配版高斯朴素贝叶斯模型的原因和原理。随着数据量的增大,单机上运行高斯朴素贝叶斯模型会变得很慢,因此考虑使用Spark来加速运行。然而,Spark的MLlib并没有实现高斯朴素贝叶斯模型,因此需要自己动手实现。文章还介绍了朴素贝叶斯的原理和公式,并对具有多个特征和类别的模型进行了讨论。最后,作者总结了实现低配版高斯朴素贝叶斯模型的步骤。 ... [详细]
author-avatar
向陽阿莫_545
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有