Prometheus 源码解读(一)
Prometheus 源码解读(一)
Prometheus 是云原生监控领域的事实标准,越来越来的开源项目开始支持 Prometheus 监控数据格式。从本篇开始,我将和大家一起阅读分析 Prometheus 源码。学习 Prometheus 的设计理念,了解 Prometheus 的局限性与不足。本系列分八个板块逐一拆解 Prometheus 源码。本文基于 Prometheus v2.13.0。
- 工作原理与架构
- 时序数据库模块(TSDB)
- 配置文件加载模块(Configuration Reloader)
- 服务发现模块(Service Discovery Manager)
- 数据抓取模块(Scrape Manager)
- RES API 模块(Web Handler)
- 查询引擎(Query Engine & PromQL)
- 性能与优劣势总结
1. Prometheus 介绍
Prometheus 是基于时序数据库(Time Series Database, TSDB)的监控告警系统。Prometheus 在 2016 年加入 CNCF 基金会,成为继 Kubernetes 后第二个毕业项目,其火热程度可见一斑。相比于传统的监控方案,Prometheus 有以下几个优势:
- 高效的存储引擎
Prometheus 将监控指标以时序数列的格式存储在时序数据库 TSDB 中。相比于传统的关系型数据库,时序数据库便于对已有数据进行聚合;在高并发的情况下,读写性能也远高于关系型数据库。Prometheus 2.0 版本重构了底层时序存储引擎。目前,单个 Prometheus 服务器可以做到每秒存储百万条指标数据,同时占用磁盘空间也很小
- 强大的查询能力:PromQL
Prometheus 有独立的 PromQL 查询语言,另外还提供了很多内置的基于时间的处理函数,降低数据聚合的难度

- 面向服务的架构
Prometheus 采用拉模型收集时序数据,数据拉取行为是由服务端来决定的。服务端可以通过某种服务发现机制来自动发现监控对象。而对于推模型的监控系统,客户端需要负责在服务端上进行注册及监控数据推送,这在微服务架构里实现起来比较难的。当大量客户端向服务的主动推送数据时,服务端的压力较大

- 与 Kubernetes 天然集成
Kubernetes 本身的指标也是以 Prometheus 格式暴露出来的
- 逐步完善的生态
OpenMetrics:Prometheus 的数据格式逐渐成为一种标准。OpenMetrics 正在从 Prometheus 的数据格式中分离出来,逐渐成为监控数据格式的国际标准
Thanos:支持数据存储的可伸缩,弥补 Prometheus 数据持久化方面的不足Prometheus
Prometheus Operator:简化 Prometheus 配置管理
2. 架构分析
图的左边开始是监控数据源。任何应用服务想要接入 Prometheus,都需要提供 HTTP 接口(通常是 x.x.x.x/metrics 地址),并暴露 Prometheus 格式的监控数据。Prometheus Server 通过 HTTP 协议周期性抓取监控目标的监控数据。Prometheus 提供了 Client 库帮助开发人员在自己的应用中集成 Prometheus 指标。
而对于不适合直接在代码中集成 Client 库的场景,比如应用来自第三方、不是由自己维护,应用不支持 HTTP 协议,那就需要为这些场景单独编写 Exporter 程序。Exporter 作为代理,把监控数据暴露出来。比如 Mysql Exporter,Node Exporter。
Prometheus 将采集到的数据存储在本地时序数据库中,但缺少数据副本。这也是 Prometheus 自身在数据持久化方面做的不足的地方。但这些存储问题都有其他的解决方案,Prometheus 支持 remote write 方式将数据存储到远端。
Prometheus 支持通过 Kubernetes、静态文本、Consul、DNS 等多种服务发现方式来获取抓取目标(targets)。最后,用户编写 PromQL 语句查询数据并进行可视化。

3. 核心组件
Prometheus 的功能由多个互相协作的组件共同完成。这些组件也即本文开头所列出的模块,比如 Service Discovery Manager。我们后续会逐一介绍。Prometheus 源码入口 main() 函数 完成参数初始化工作,并依次启动各依赖组件。
首先,main 函数解析命令行参数(详见附录 A),并读取配置文件信息(由 --config.file 参数提供)。Prometheus 特别区分了命令行参数配置(flag-based configuration)和文件配置(file-based configuration)。前者用于简单的设置,并且不支持热更新,修改需要启停 Prometheus Server 一次;后者支持热更新。
main 函数完成初始化、启动所有的组件。这些组件包括:Termination Handler、Service Discovery Manager、Web Handler 等。各组件是独立的 Go Routine 在运行,之间又通过各种方式相互协调,包括使用 Channel、引用对象 Reference、传递 Context。
这些 Go Routine 的协作使用了 oklog/run 框架。oklog/run 是一套基于 Actor 设计模式的 Go Routine 编排框架,实现了多个 Go Routine 作为统一整体运行并有序依次退出。这在很多开源项目中都有使用,进一步了解可参考作者的另一篇文章《Go routine 编排框架:oklog/run 包》

4. 参考文档
「K8S 技术落地实践」Prometheus 在 K8S 上的监控实践 来自本文作者在杭州容器 Meetup 的分享
Prometheus Internal architecture
附录 A:Prometheus 启动参数
- web:Prometheus 服务器 HTTP 连接参数,REST API 启用相关参数,Prometheus Console 网页配置
- storage:TSDB 相关配置
- query:查询执行相关配置
| 参数名 | 解释 |
|---|---|
| config.file | 配置文件的位置,包含抓取监控对象列表(用于服务发现)和 recording rules 文件位置 |
| web.listen-address | Prometheus server 端监听请求(API 请求、Dashboard 界面)的地址和端口,默认本地端口 9090 |
| web.read-timeout | 设置 Prometheus server 读取客户端请求的超时时间。以此来避免客户端因超慢的写操作,长时间占用链接资源。ReadTimeout 覆盖了从连接请求被接受到请求报文被完全读取的时间。默认 5m |
| web.max-connections | 最大连接数,默认 512 |
| web.external-url | 设置 Prometheus 对外的 URL。需要设置外部访问的 Prometheus 通常因为启用了反向代理。如果 external-url 包含路径,则 Prometheus 所有对外的接口,都会带上该路径作为前缀。eg. http://<host>:<port>/<path>/api/v1/query?query=up |
| web.route-prefix | 用于替换 external-url 的路径前缀,eg. http://<host>:<port>/<route-prefix>/api/v1/query?query=up |
| web.user-assets | 网页静态 asset 文件夹路径 |
| web.enable-lifecycle | 开启后,可以实现通过请求 /-/reload 热加载更新配置,默认 false |
| web.enable-admin-api | 开启后,允许使用一些管理员级别的 api,包括删除时间序列等,/api/v1/admin/tsdb/delete_series。默认 false |
| web.console.templates | Prometheus Console 网站模板文件夹路径 |
| web.console.libraries | Prometheus Console 使用的库路径 |
| web.page-title | Console 页面标题 |
| web.cors.origin | 设置 Prometheus 服务端允许的域,用正则表达式表示。eg. https?://(domain*)\.com |
| storage.tsdb.path | 监控数据存储路径,默认 data/ |
| storage.tsdb.min-block-duration | 设置数据块最小时间跨度,默认 2h 的数据量。监控数据是按块(block)存储,每一个块中包含该时间窗口内的所有样本数据(data chunks) |
| storage.tsdb.max-block-duration | 设置数据块最大时间跨度,默认为最大保留时间的 10% |
| storage.tsdb.wal-segment-size | 设置 WAL 分段存储每个分段的大小。默认 128MB |
| storage.tsdb.retention.time | 监控数据最大保留时间,默认 15d |
| storage.tsdb.no-lockfile | 不在数据存储目录中创建文件锁 |
| storage.tsdb.wal-compression | 开启后,会对 WAL 文件进行压缩(成本是带来 CPU 开销)。默认 false |
| storage.remote.flush-deadline | |
| storage.remote.read-sample-limit | 一次最多从远端存储中读取采样数据量,默认 5e7 条,0 表示无限制 |
| storage.remote.read-concurrent-limit | 最大并发读,默认 10 个请求,0 表示无限制 |
| rules.alert.for-outage-tolerance | |
| rules.alert.for-grace-period | |
| rules.alert.resend-delay | |
| alertmanager.notification-queue-capacity | |
| alertmanager.timeout | |
| query.lookback-delta | 在计算 PromQL 表达式结果时,最大回看时间 |
| query.timeout | 查询超时时间 |
| query.max-concurrency | 最大并发处理查询请求数,默认 20 个请求 |
| query.max-samples | 能载入到内存中最大采样数据量,默认 5e7 条 |
Prometheus 源码解读(一)的更多相关文章
- SDWebImage源码解读之SDWebImageDownloaderOperation
第七篇 前言 本篇文章主要讲解下载操作的相关知识,SDWebImageDownloaderOperation的主要任务是把一张图片从服务器下载到内存中.下载数据并不难,如何对下载这一系列的任务进行设计 ...
- SDWebImage源码解读 之 NSData+ImageContentType
第一篇 前言 从今天开始,我将开启一段源码解读的旅途了.在这里先暂时不透露具体解读的源码到底是哪些?因为也可能随着解读的进行会更改计划.但能够肯定的是,这一系列之中肯定会有Swift版本的代码. 说说 ...
- SDWebImage源码解读 之 UIImage+GIF
第二篇 前言 本篇是和GIF相关的一个UIImage的分类.主要提供了三个方法: + (UIImage *)sd_animatedGIFNamed:(NSString *)name ----- 根据名 ...
- SDWebImage源码解读 之 SDWebImageCompat
第三篇 前言 本篇主要解读SDWebImage的配置文件.正如compat的定义,该配置文件主要是兼容Apple的其他设备.也许我们真实的开发平台只有一个,但考虑各个平台的兼容性,对于框架有着很重要的 ...
- SDWebImage源码解读_之SDWebImageDecoder
第四篇 前言 首先,我们要弄明白一个问题? 为什么要对UIImage进行解码呢?难道不能直接使用吗? 其实不解码也是可以使用的,假如说我们通过imageNamed:来加载image,系统默认会在主线程 ...
- SDWebImage源码解读之SDWebImageCache(上)
第五篇 前言 本篇主要讲解图片缓存类的知识,虽然只涉及了图片方面的缓存的设计,但思想同样适用于别的方面的设计.在架构上来说,缓存算是存储设计的一部分.我们把各种不同的存储内容按照功能进行切割后,图片缓 ...
- SDWebImage源码解读之SDWebImageCache(下)
第六篇 前言 我们在SDWebImageCache(上)中了解了这个缓存类大概的功能是什么?那么接下来就要看看这些功能是如何实现的? 再次强调,不管是图片的缓存还是其他各种不同形式的缓存,在原理上都极 ...
- AFNetworking 3.0 源码解读 总结(干货)(下)
承接上一篇AFNetworking 3.0 源码解读 总结(干货)(上) 21.网络服务类型NSURLRequestNetworkServiceType 示例代码: typedef NS_ENUM(N ...
- AFNetworking 3.0 源码解读 总结(干货)(上)
养成记笔记的习惯,对于一个软件工程师来说,我觉得很重要.记得在知乎上看到过一个问题,说是人类最大的缺点是什么?我个人觉得记忆算是一个缺点.它就像时间一样,会自己消散. 前言 终于写完了 AFNetwo ...
随机推荐
- Springboot+Shiro+Mybatis+mysql
一 .shiro框架 Shiro是Apache 的一个强大且易用的Java安全框架,执行身份验证.授权.密码学和会话管理.Shiro 主要分为两个部分就是认证和授权两部分 1.Subject代表了当前 ...
- JAVA WEB中的Servlet过滤器
实现一个Servlet过滤器,可以对用户登录情况进行控制.要求如下: 1)访问路径是admin下的资源,需要登录,如果用户没有登录,自动转向用户登录页面.用户登录成功后,再次访问admin下的资源不需 ...
- .Net轻量状态机Stateless
很多业务系统开发中,不可避免的会出现状态变化,通常采用的情形可能是使用工作流去完成,但是对于简单场景下,用工作流有点大财小用感觉,比如订单业务中,订单状态的变更,涉及到的状态量不是很多,即使通过简单的 ...
- 安装MariaDB
1.安装MariaDB安装命令yum -y install mariadb mariadb-server安装完成MariaDB,首先启动MariaDBsystemctl start mariadb设置 ...
- spring项目与logstash和Elasticsearch整合
原创/朱季谦 最近在做一个将项目日志通过logstash传到Elasticsearch的功能模块,经过一番捣鼓,终于把这个过程给走通了,根据自己的经验,做了这篇总结文章,希望可以给各位玩logst ...
- 自己制作一个简单的操作系统二[CherryOS]
自己制作一个简单的操作系统二[CherryOS] 我的上一篇博客 自己制作一个简单的操作系统一[环境搭建], 详细介绍了制作所需的前期准备工作 一. 一点说明 这个操作系统只是第一步, 仅仅是开机显示 ...
- UnicodeDecodeError: 'gbk' codec can't decode byte 0xb0 in position 279: illegal multibyte sequence
with open(r'E:\yy\mysql.txt') as wk: print(wk.readlines()) Traceback (most recent call last): File & ...
- windows环境下搭建python虚拟环境及离线移植
以python3.6为例 ①安装virtualenv: #pip安装之后在D:\Python36\Scripts目录下可以看到多了一个virtualenv.exe可执行文件pip install vi ...
- asp.net core IdentityServer4 实现 resource owner password credentials(密码凭证)
前言 OAuth 2.0默认四种授权模式(GrantType) 授权码模式(authorization_code) 简化模式(implicit) 密码模式(resource owner passwor ...
- SpringBootSecurity学习(04)网页版登录其它授权和登录处理
其它授权配置 security的配置类中,对所有路径进行了统一授权配置.但是有的内容我们也需要让未登录游客有权限访问,比如js,css等静态文件,还有一些宣传页面等等.这些路径可以单独配置: 我们来试 ...