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 源码解读(一)的更多相关文章

  1. SDWebImage源码解读之SDWebImageDownloaderOperation

    第七篇 前言 本篇文章主要讲解下载操作的相关知识,SDWebImageDownloaderOperation的主要任务是把一张图片从服务器下载到内存中.下载数据并不难,如何对下载这一系列的任务进行设计 ...

  2. SDWebImage源码解读 之 NSData+ImageContentType

    第一篇 前言 从今天开始,我将开启一段源码解读的旅途了.在这里先暂时不透露具体解读的源码到底是哪些?因为也可能随着解读的进行会更改计划.但能够肯定的是,这一系列之中肯定会有Swift版本的代码. 说说 ...

  3. SDWebImage源码解读 之 UIImage+GIF

    第二篇 前言 本篇是和GIF相关的一个UIImage的分类.主要提供了三个方法: + (UIImage *)sd_animatedGIFNamed:(NSString *)name ----- 根据名 ...

  4. SDWebImage源码解读 之 SDWebImageCompat

    第三篇 前言 本篇主要解读SDWebImage的配置文件.正如compat的定义,该配置文件主要是兼容Apple的其他设备.也许我们真实的开发平台只有一个,但考虑各个平台的兼容性,对于框架有着很重要的 ...

  5. SDWebImage源码解读_之SDWebImageDecoder

    第四篇 前言 首先,我们要弄明白一个问题? 为什么要对UIImage进行解码呢?难道不能直接使用吗? 其实不解码也是可以使用的,假如说我们通过imageNamed:来加载image,系统默认会在主线程 ...

  6. SDWebImage源码解读之SDWebImageCache(上)

    第五篇 前言 本篇主要讲解图片缓存类的知识,虽然只涉及了图片方面的缓存的设计,但思想同样适用于别的方面的设计.在架构上来说,缓存算是存储设计的一部分.我们把各种不同的存储内容按照功能进行切割后,图片缓 ...

  7. SDWebImage源码解读之SDWebImageCache(下)

    第六篇 前言 我们在SDWebImageCache(上)中了解了这个缓存类大概的功能是什么?那么接下来就要看看这些功能是如何实现的? 再次强调,不管是图片的缓存还是其他各种不同形式的缓存,在原理上都极 ...

  8. AFNetworking 3.0 源码解读 总结(干货)(下)

    承接上一篇AFNetworking 3.0 源码解读 总结(干货)(上) 21.网络服务类型NSURLRequestNetworkServiceType 示例代码: typedef NS_ENUM(N ...

  9. AFNetworking 3.0 源码解读 总结(干货)(上)

    养成记笔记的习惯,对于一个软件工程师来说,我觉得很重要.记得在知乎上看到过一个问题,说是人类最大的缺点是什么?我个人觉得记忆算是一个缺点.它就像时间一样,会自己消散. 前言 终于写完了 AFNetwo ...

随机推荐

  1. charles Web界面设置

    本文参考:charles Web界面设置 Web Inerface Web界面可以让您使用Web浏览器控制查询,您可以访问 http://control.charles 的Web界面,当查询运行时,您 ...

  2. charles 访问控制设置

    本文参考:charles 访问控制设置 charles 访问控制设置 access control settings 访问账户设置: 这里可以配置连接到charles时的一些配置: 这个访问控制确定谁 ...

  3. 如何从请求、传输、渲染3个方面提升Web前端性能

    什么是WEB前端呢?就是用户电脑的浏览器所做的一切事情.我们来看看用户访问网站,浏览器都做了哪些事情: 输入网址 –> 解析域名 -> 请求页面 -> 解析页面并发送页面中的资源请求 ...

  4. scrapy框架来爬取壁纸网站并将图片下载到本地文件中

    首先需要确定要爬取的内容,所以第一步就应该是要确定要爬的字段: 首先去items中确定要爬的内容 class MeizhuoItem(scrapy.Item): # define the fields ...

  5. 首次接触flask遇到socket.error: [Errno 10013] 报错

    解决方案: 发现是因为端口5000被占用了,设置一个其他port就行:app.run(port=5050)

  6. springboot之全局处理统一返回

    springboot之全局处理统一返回 简介 在REST风格的开发中,避免通常会告知前台返回是否成功以及状态码等信息.这里我们通常返回的时候做一次util的包装处理工作,如:Result类似的类,里面 ...

  7. 数位DP 详解

    序 天堂在左,战士向右 引言 数位DP在竞赛中的出现几率极低,但是如果不会数位DP,一旦考到就只能暴力骗分. 以下是数位DP详解,涉及到的例题有: [HDU2089]不要62 [HDU3652]B-n ...

  8. java8 Optional使用总结

    [前言] java8新特性 java8 函数接口 java8 lambda表达式 Java 8 时间日期使用 java8 推出的Optional的目的就是为了杜绝空指针异常,帮助开发者开发出更优雅的代 ...

  9. postman工具使用小结

    序言 现在,postman在做接口测试方面,发挥着越来越重大的作用,其支持多种请求方式.并可以模拟各种类型的数据请求类型,在实际开发中使用它可以极大的提高开发的效率. 安装postman 1.  安装 ...

  10. 深入理解 DeepSea 和 Salt 部署工具 - Storage6

    学习 SUSE Storage 系列文章 (1)SUSE Storage6 实验环境搭建详细步骤 - Win10 + VMware WorkStation (2)SUSE Linux Enterpri ...