Prometheus技术秘笈(txt+pdf+epub+mobi电子书下载)

作者:百里燊

出版社:人民邮电出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Prometheus技术秘笈

Prometheus技术秘笈试读:

前言

无论是在互联网公司还是在传统IT公司,监控系统都占有非常重要的地位。运维人员通过监控数据以及告警通知可以实时了解系统的运行状态,开发人员可以通过监控数据快速定位系统的性能瓶颈。

目前在市场上除Zabbix等老牌的监控系统之外,新兴监控系统也逐步崛起,例如本书将要介绍的Prometheus、小米公司开源的Open-Falcon等。另外,很多时序数据库(如InfluxDB和OpenTSDB等)也被作为自研监控系统的存储层。相信读者即使在生产实践中没有接触过时序数据库,也一定对其有所耳闻。例如,在2016年,百度云在其物联网平台上发布了国内首个多租户的分布式时序数据库产品TSDB;阿里云在“2017云栖大会•上海峰会”上发布了面向物联网场景的高性能时间序列数据库HiTSDB等。时序数据库作为物联网中的基础设施之一,得到了各个互联网巨头企业的重视,其热门程度可见一斑。

与其说Prometheus是一个监控系统,不如说Prometheus提供了一个完备的监控生态。本书将会深入介绍Prometheus生态中的核心组件,例如Prometheus TSDB、Prometheus Server、AlertManager和Client等,并且详细剖析这些核心组件的工作原理以及核心实现。如何阅读本书

由于篇幅限制,本书并没有详细介绍Go语言的基础知识,但为了便于理解Prometheus的实现细节,需要读者对Go语言的基本语法有一定的了解。

本书共分为11章,主要从源码角度深入剖析Prometheus各个组件的核心原理和代码实现。各章之间的内容相对独立,对Prometheus有一定了解的读者可以有目标地选择合适的章节开始阅读,当然也可以从第1章开始向后逐章阅读。本书主要以Prometheus的2.5.0版本为基础进行介绍。

第1章首先介绍了Prometheus在时序数据库以及监控领域所处的地位,然后详细介绍了InfluxDB、Graphite、OpenTSDB和Open-Falcon的架构特点及其优缺点。接下来对Prometheus生态的核心架构和关键组件的功能进行概述,对其各个核心组件的功能进行了简要说明。最后还介绍了Prometheus的安装流程、源码环境的搭建流程以及Grafana接入Prometheus的操作步骤。

第2章介绍prometheus.yml配置文件中核心的配置项,其中结合示例介绍了各核心配置项的含义和功能。

第3章介绍了Prometheus TSDB,它是Prometheus本地时序存储的实现,也是Prometheus的核心模块。这里首先阐述Facebook Gorilla论文的核心思想,该思想是Prometheus TSDB实现的基础。之后介绍了Prometheus TSDB在磁盘上的目录与文件的组织方式、含义和功能。随后详细分析了Prometheus TSDB时序存储的核心实现,其中介绍了Chunk接口实现、Meta元数据结构以及读写时序数据用到的ChunkWriter和ChunkReader的实现等内容。

接下来介绍的是Prometheus TSDB中的index文件,深入剖析了index文件中各个部分内容的读写流程。之后对Prometheus TSDB使用的WAL日志文件的物理结构和逻辑结构进行了深入分析,同时详细分析了Checkpoint机制的相关内容。随后介绍了Prometheus TSDB如何通过tombstones文件实现“标记删除”功能。

在第3章中还对Prometheus TSDB的压缩计划生成以及具体压缩操作的执行逻辑和实现进行了全方位的剖析。最后,深入介绍了Prometheus TSDB中内存Head窗口涉及的基础组件以及内存Head窗口中数据的存储方式、读写等内容。

第4章介绍了Prometheus中的scrape模块,主要涉及scrape模块如何根据prometheus.yml 文件中的配置信息周期性地从客户端、exporter或PushGateway抓取时序数据,以及Relabel操作的具体实现。

第5章介绍了Prometheus Server中的storage模块,该模块的核心功能是对本地存储和远程存储进行封装和适配。

第6章介绍了Prometheus Server中V1版本的HTTP API接口,该版本主要提供了执行PromQL语句、查询时序元数据、根据Label Name查询Label Value、查询target和查询Rule的功能。另外,HTTP API接口还提供了一些Admin管理的功能。

第7章详细介绍了PromQL语句的执行流程,其中涉及PromQL的解析、抽象语法树中每个节点的执行流程等内容。

第8章介绍了Prometheus Server中与Rule相关的模块。首先介绍了Recording Rule配置以及Alerting Rule配置在内存中的抽象,以及Prometheus如何管理这些Rule配置;然后介绍了Recording Rule以及Alerting Rule的执行流程;最后分析了notifier模块的实现,它的核心逻辑是将Alerting Rule产生告警的时序信息发送到AlertManager集群。

第9章介绍了Prometheus Server中discovery模块的核心接口和实现。discovery模块负责接入多种服务发现组件,让Prometheus Server能够动态发现target信息以及AlertManager 信息。

第10章介绍了AlertManager。首先介绍了AlertManager中核心模块的功能以及整个AlertManager的核心架构;随后的章节深入分析了AlertManager中每个核心模块的工作原理和具体实现。

第11章介绍了Prometheus Client(Golang版本)的核心原理以及相关实现。首先介绍了Prometheus Client中的4种基本数据类型的特点和使用场景;然后以Gauge为例,深入分析了Prometheus Client记录监控的思想以及涉及的核心组件;接下来以Node Exporter为例介绍了Exporter大致实现原理。

如果读者在阅读本书的过程中,发现任何不妥之处,请将您宝贵的意见和建议发送到邮箱shen_baili @163.com,也欢迎读者朋友通过此邮箱与我进行交流。关于作者

百里燊,硕士研究生毕业,小时候想成为闯荡江湖的侠客,结果着迷于代码,最终成为辛勤工作的程序员。目前关注各种开源时序数据库,期待与大家共同进步。联系邮箱:shen_baili@163.com。致谢

感谢人民邮电出版社的陈聪聪老师,是您的辛勤工作让本书的出版成为可能。同时还要感谢许多我不知道名字的幕后工作人员为本书付出的努力。

感谢三十在技术上提供的帮助。

感谢三白和陈默同学对我的鼓励和支持。

感谢冯玉玉同学和李成伟同学,你们是我生活中的灯塔。

感谢我的母亲,谢谢您的付出和牺牲!资源与支持

本书由异步社区出品,社区(https://www.epubit.com/)为您提供相关资源和后续服务。提交勘误

作者和编辑尽最大努力来确保书中内容的准确性,但难免会存在疏漏。欢迎您将发现的问题反馈给我们,帮助我们提升图书的质量。

当您发现错误时,请登录异步社区,按书名搜索,进入本书页面,点击“提交勘误”,输入勘误信息,单击“提交”按钮即可。本书的作者和编辑会对您提交的勘误进行审核,确认并接受后,您将获赠异步社区的100积分。积分可用于在异步社区兑换优惠券、样书或奖品。与我们联系

我们的联系邮箱是contact@epubit.com.cn。

如果您对本书有任何疑问或建议,请您发邮件给我们,并请在邮件标题中注明本书书名,以便我们更高效地做出反馈。

如果您有兴趣出版图书、录制教学视频,或者参与图书翻译、技术审校等工作,可以发邮件给我们;有意出版图书的作者也可以到异步社区在线提交投稿(直接访问www.epubit.com/selfpublish/submission即可)。

如果您是学校、培训机构或企业,想批量购买本书或异步社区出版的其他图书,也可以发邮件给我们。

如果您在网上发现有针对异步社区出品图书的各种形式的盗版行为,包括对图书全部或部分内容的非授权传播,请您将怀疑有侵权行为的链接发邮件给我们。您的这一举动是对作者权益的保护,也是我们持续为您提供有价值的内容的动力之源。

关于异步社区和异步图书“异步社区”是人民邮电出版社旗下IT专业图书社区,致力于出版精品IT技术图书和相关学习产品,为作译者提供优质出版服务。异步社区创办于2015年8月,提供大量精品IT技术图书和电子书,以及高品质技术文章和视频课程。更多详情请访问异步社区官网https://www.epubit.com。“异步图书”是由异步社区编辑团队策划出版的精品IT专业图书的品牌,依托于人民邮电出版社近30年的计算机图书出版积累和专业编辑团队,相关图书在封面上印有异步图书的LOGO。异步图书的出版领域包括软件开发、大数据、AI、测试、前端、网络技术等。异步社区微信服务号第1章 Prometheus基础入门

Prometheus是一款时下比较先进的时序数据库,也被认为是下一代的监控系统。在时序数据库2019年3月的排名中,Prometheus排名已经超越老牌时序数据库OpenTSDB,跃居第5名的位置,如图1-1所示。图1-11.1 时序数据库对比

下面将从数据存储和监控系统两个层面介绍一下常见的时序数据库和监控系统,帮助读者迅速了解它们的特性,方便读者根据自己的使用场景进行选型。1.1.1 InfluxDB简介

InfluxDB是使用Golang语言编写的一款时序数据,目前较新的版本为2.0 Alpha版本,稳定版是1.7.5版本。InfluxDB在时序数据库方面的市场占有率较大,其热度之所以如此之高,与以下特点有着直接关系。1.读写性能

InfluxDB在时序数据写入、数据压缩以及实时查询等方面的表现都非常出众。InfluxDB官方网站将InfluxDB与Cassandra、Elasticsearch、MongoDB、OpenTSDB进行了性能以及磁盘占用量的比较,结果表明InfluxDB在时序数据读写性能方面,较市面上其他的数据库产品有较大的优势。2.支持多种接口

InfluxDB提供了多种通用接口,例如HTTP API和GRPC等;也支持多种时序数据库协议,例如Graphite、Collectd和OpenTSDB等。这就方便了时序数据的写入以及InfluxDB与其他时序产品之间的数据迁移。3.支持类SQL的查询语句

用户可以通过书写InfluxQL语句来查询InfluxDB中的时序数据。InfluxQL是一种类SQL的查询语言,这就降低了InfluxDB的使用门槛;同时InfluxQL也支持多种函数和表达式,方便用户实现一些高级功能。4.数据压缩

对于近期的时序数据,InfluxDB会保存其原始数据;对于较久的时序数据,InfluxDB会进行Downsampling处理,对数据进行聚合处理,聚合之后的时序数据精度会降低,但数据量会减少,这样就可以降低磁盘占用量,这也算是InfluxDB在数据精度和磁盘使用量之间的折中设计。另外,InfluxDB可以开启定期清理过期数据的功能,进一步释放磁盘空间。

单从时序数据的存储方面来看,InfluxDB已经非常先进,Prometheus TSDB在某些方面的设计与InfluxDB非常类似。从一个监控系统的角度来看,InfluxDB之前的相关生态比较匮乏,但是近几年InfluxData以InfluxDB为中心,打造了很多配套组件,形成了一个完整的生态系统,也被称为“TCIK Stack”,如图1-2所示。图1-2

这里简单介绍一下InfluxDB相关组件的功能。● Telegraf:Agent组件。Telegraf用于收集各个系统产生的时序数

据以及事件信息,并将其push到InfluxDB进行持久化。● Kapacitor:流处理引擎。Kapacitor可以从InfluxDB或是Telegraf

获取时序数据或时事件信息,然后根据用户自定义逻辑进行处

理,处理结果可以写回InfluxDB存储,也可以发送到外部的报警

模块用于报警处理。另外,Kapacitor的开源版本有一些功能上的

缺失,感兴趣的读者可以参考InfluxDB的官方文档。● Chronograf:可视化管理平台。Chronograf提供了可视化的查询

界面以及插件化的Dashboard,虽然其可视化功能比Prometheus

强大,但是与发展成熟且插件众多的Grafana相比还是有一定差

距。

InfluxDB的高可用以及集群方案目前并不开源,用户只能在企业版或是InfluxCloud上付费使用,且价格不菲,这也是很多企业放弃使用InfluxDB的原因之一。有些用户在InfluxDB单机版本之上,根据自身业务通过Sharding的方式建立了InfluxDB集群,但这种方式并不通用。目前市面上还没有开源的通用InfluxDB集群方案。1.1.2 Graphite简介

Graphite 是一个企业级的监控工具,能够在配置较低的硬件上运行。Graphite一般用于监控机器指标,例如CPU使用率、内存使用量、I/O利用率和网络延迟等,当然Graphite也可以用于记录应用监控。

Graphite与InfluxDB类似,本身并不收集时序数据,只提供了写入时序数据的接口。常与Graphite搭配使用的采集工具是Collectd。Collectd于2012年被Graphite作为其采集时序数据的插件吸收到项目中。Collectd的功能非常强大,可以捕获几乎全部的机器信息,目前也支持获取Java应用的基础信息以及Redis的监控信息。

Graphite的架构如图1-3所示。图1-3

下面来简单介绍一下Graphite的核心模块。● Carbon:监控数据的接收服务。Carbon实际上是一个守护进

程,当Carbon接收到监控数据时,会调用Whisper进行存储。● Whisper:Whisper是RRD格式的数据库,它期望时序数据按照固

定间隔写入。每一条时序数据都会被存储在一个独立的文件中。

在系统运行一定时间之后,新的时序数据会覆盖旧的数据,用来

持久化收集到的时序数据。● Graphite API:支撑Graphite的Web UI,Graphite Web UI会通过

该RESR API接口从Graphite中获取数据并进行展示。多数情况

下,会直接使用Grafana作为可视化系统,而不是直接使用

Graphite自带的Web UI。

作为一个历史悠久的时序数据库,Graphite拥有众多的插件、庞大的社区支持、完备的文档和资料。此外,其集群方案比较成熟,安装使用也相对简单。但是Graphite也有一些缺点。● RRD格式的存储要求时序数据写入间隔固定,在某些场景中,

需要进行一些额外操作,处理乱序到达的数据。● 查询时序的接口比较简单,不支持类SQL的查询语言。● 缺乏复制和一致性的保证。● 时序数据的读写效率不高。● 报警等功能缺失,当然,这可以通过其他开源插件和服务进行弥

补。● RDD格式的数据库一般都是单指标单文件的设计,也都面临I/O

消耗较高,磁盘资源使用量较大的问题。1.1.3 OpenTSDB简介

OpenTSDB是一款基于HBase存储的时序数据库。时序数据在OpenTSDB中的逻辑模型与Prometheus基本类似,两者都是通过metric以及tag(label)标识一条时序。图1-4展示了OpenTSDB的核心架构。图1-4

OpenTSDB本身是无状态的,可以部署多个节点以实现高可用,底层存储依赖于HBase进行持久化,由于HBase自身就拥有多副本、高可用的特性,因此OpenTSDB不必再关注这些问题。但是,OpenTSDB也并不是一个完美的解决方案,它自身也是有一些问题的。● 底层依赖的Hadoop和HBase本身也会引入一些复杂性。● 在OpenTSDB的 HBase RowKey设计中,会将metric和tag字符串

转换成UID之后进行拼接,同时也加入了salt字段。如果某个

metric出现大量时序,则会造成HBase的热点问题。● OpenTSDB没有针对时序数据的特性进行压缩,而是依赖底层的

HBase对数据进行压缩。● OpenTSDB不支持类SQL的查询语句,而且OpenTSDB支持的函

数较少。● OpenTSDB没有自动聚合以及自动Downsampling的功能,也不

支持预定义聚合规则,而是在查询时进行聚合或是

Downsampling处理,这就可能导致查询请求的返回时间较长。● 自带的Web UI功能单一,实践中一般使用Grafana作为UI界面。● OpenTSDB不提供报警的相关组件。1.1.4 Open-Falcon简介

Open-Falcon是由小米开源的一套监控系统,在国内很多互联网企业中都有应用。从本质上来说,Open-Falcon并不仅仅是时序数据库,还是一套完整的监控方案。Open-Falcon是一个比较大的分布式系统,总共有十多个组件。如果按照功能划分,这十几个组件可以划分为基础组件、存储组件和报警链路组件,其架构如图1-5所示。图1-5

下面简单介绍一下Open-Falcon中各个核心组件的功能。● Falcon-Agent:Falcon-Agent用于采集机器的基础监控指标,例

如CPU指标、机器负载和Disk利用率等,每隔60s的时间Falcon-

Agent会将收集到的监控信息推送(push)到Transfer。● Transfer:Transfer是监控数据的转发服务。它会接收Agent上报

的时序数据,然后按照哈希规则进行数据分片,并将分片后的数

据分别推送给Graph和Judge等组件。另外,Transfer也可以将监

控数据推送到其他存储中进行扩展。● Graph:Graph是存储时序数据的组件。它会将Transfer组件推送

的监控数据进行持久化处理,同时也会处理API组件的查询请求。

Graph使用RRDTool保存时序数据,与Whisper类似,Graph也会

为每个指标生成一个独立的RRD文件。同时,Graph还会对时序

数据进行采样,计算最大值、最小值和平均值,并保存历史数据

的归档,这样既可以节省存储空间,又可以防止查询长时间段的

时序数据时一次返回数据量过大的情况发生。● API组件:API组件提供了统一的Rest接口。API组件接收到上层

发送的查询请求时,会按照一致性Hash算法到相应的Graph实例

查询不同metric的数据,在获取时序数据之后进行汇总,并返回

给上层模块。● Aggreggator:Aggreggator负责聚合集群中所有机器的某个指标

值,提供一种集群视角的监控试图。● Judge:Judge用于告警判断,Transfer在将监控数据转发给

Graph组件进行持久化的同时,还会将其转发给Judge用于判断

是否触发告警。在监控数据量较大的场景中,一个Judge实例很

难及时处理所有报警,因此Transfer会通过一致性哈希(Hash)

来进行分片,每个Judge实例只需要处理一小部分时序数据即可。● Alarm:Judge会将告警的判定结果暂存到Redis集群中。Alarm模

块从Redis中读取判定结果并进行处理,然后通过不同渠道的进

行发送。Alarm处理告警时会对高级别的告警进行优先处理,同

时将告警记录保存到MySQL中,后续可用于生成相应报表。另

外,告警合并等功能也是在Alarm模块中完成的。

Open-Falcon涉及的组件虽然很多,但是其中绝大多数都是无状态的,可以进行水平扩展。Open-Falcon依赖的存储,例如MySQL、Redis等,也都有成熟的高可用方案。但Open-Falcon的缺点也比较明显。● Graph实际上是以RDD格式进行存储,当监控数据量逐渐变大的

时候,磁盘的I/O就会出现瓶颈,“高需求低产出”的评价也多次

出现在Open-Falcon的社区中。当然,有一些开发人员开始尝试

借鉴Facebook Gorilla思想对其进行优化,但在Open-Falcon 0.2.2

版本中,我未找到相关的优化信息。● 精确的历史数据保存时间短,不利于历史的现场回放。● Open-Falcon整个架构中最大的问题在于Alarm是一个单点。● Open-Falcon自身有一些Bug和性能问题需要优化,例如Graph写

入瓶颈的问题、Hash不均匀导致数据在多个Graph实例之间分布

不均匀的情况等。1.2 Prometheus架构概述

本节开始介绍本书的主角——Prometheus。有人说Prometheus是一个时序数据库,也有人说Prometheus是一套监控方案,我觉得Prometheus更像是一个完备的监控生态系统,图1-6来自Prometheus官方文档,展示了Prometheus整个生态中的核心组件。图1-6

在Prometheus的配置文件中,用户可以指定具体监控的对象(见图1-6中的Prometheus target),这些target可以有多种类型,具体如下。● 对于长时间运行的job,可以使用Prometheus Client记录并暴露

监控。Prometheus Client中提供了多种指标类型,其中

Histogram和Summary两种类型都包含了统计含义。● 对于机器监控、MySQL等第三方监控,Prometheus官方提供了

很多exporter,用户可以通过部署exporter将第三方的监控数据按

照Prometheus的格式暴露出来。在后面介绍Prometheus Golang

版本客户端的章节中,会选取众多exporter组件中的一个进行深

入分析。● 对于短时间执行的job,可以先将监控数据通过push方式推送到

Pushgateway中缓存。另外,当target与Prometheus之间有网络

隔离的时候,也可以利用Pushgateway来进行中转。

Prometheus Server中的scrape模块会周期性地从上述3类客户端组件中拉取(pull)监控数据,那么Prometheus Server如何知道这些客户端暴露的地址呢?用户可以在prometheus.yml配置文件中静态配置,也可以使用Prometheus支持的服务发现组件(图1-6中的discovery模块)动态获取,针对每个job的抓取周期也可以在prometheus.yml配置文件中进行指定。

Prometheus Server在抓取监控数据之后会将其进行持久化处理,Prometheus同时提供了本地存储和远程存储,后续会详细分析Prometheus本地TSDB存储的原理和核心实现。Prometheus本地TSDB存储的读写能力以及对时序数据的压缩能力都非常好,但整个系统的吞吐量上限、伸缩性、高可用等方面最终还是受限于单台服务器。Prometheus通过支持远程存储来解决这个问题,用户可以通过配置同时使用多个远程存储,也可以指定每个远程存储只读、只写或同时支持读写。目前Prometheus支持的远程存储包括CrateDB、Elasticsearch、Graphite、InfluxDB、Kafka、OpenTSDB、PostgreSQL、TimescaleDB和TiKV等。至于远程存储的使用方式,请读者阅读后面的内容之后,参考Prometheus官方文档中两部分的相关内容进行学习。

Prometheus Server持久化监控数据之后,客户端就可以通过PromQL语句进行查询了。PromQL是Prometheus提供的结构化查询语言,支持Instant vector(瞬时值查询)、Range vector(范围查询)、多种function以及多种聚合操作,可以帮助用户轻松实现复杂的查询逻辑,后面会专门来介绍PromQL的实现。

为了方便用户查询监控数据,Prometheus Server自带了一个Web UI界面,实际工作中更多的是使用Grafana作为前端展示界面,用户也可以直接使用Client请求Prometheus Server读取时序数据。

在某些特殊场景中,用户需要频繁执行一条复杂的PromQL语句来获取监控数据,这条PromQL语句可能会涉及多条时序以及一些复杂的聚合操作或函数操作,其执行时间也会比较长。为了解决此类问题,Prometheus提供了自定义Recording Rule的功能,用户可以将上述复杂的PromQL语句定义成一条Recording Rule。Prometheus会根据Recording Rule的配置定期执行该PromQL语句,并将其结果作为一条新的时序数据进行持久化。之后,用户在查询过程中就不用实时执行这条复杂的PromQL语句了,直接查询Recording Rule对应的时序即可得到正确结果。

AlertManager是Prometheus生态中的告警组件,Prometheus可以配置多个AlertManager实例以形成一个AlertManager集群,Prometheus可以通过Discovery模块动态发现AlertManager集群中各个节点的上下线,这就避免了单点的问题。AlertManager组件的核心实现以及AlertManager集群中多个实例之间的通信,在后面会专门进行分析,其中还会将Prometheus AlertManager与其他告警组件进行简单对比,帮助读者进行选型。当前版本的AlertManager组件支持多种方式的告警通知方式,实践中常用的有Email、WeChat和Webhook等。

本章剩余的内容将介绍Prometheus的安装、Prometheus源码环境的搭建以及prometheus.yml配置文件中核心配置的含义。1.3 快速安装Prometheus

Prometheus的安装、配置操作相对于前面介绍的时序数据库(以及监控系统)来说是非常重要的。首先,可以从Prometheus官网下载Prometheus的二进制包,这里以Mac版本的Prometheus 2.8.0版本为例,并执行如下命令进行解压。tar xvfz prometheus-2.8.0.darwin-amd64.tar.gzcd prometheus-2.8.0.darwin-amd64

在解压之后的目录中,找到一个名为prometheus的二进制包,执行如下命令可以看到其相关参数。prometheus --help

在该目录下,可以找到Prometheus Server的核心配置文件——prometheus.yaml,这里简单看一下安装包中自带的prometheus.yaml配置文件内容以及各个配置项的含义。# 默认配置文件中有3个部分,分别是global、rule_files以及scrape_configs# global部分进行了Prometheus Server全局配置global: # scrape_interval指定了Prometheus Server抓取一个target的时间间隔,在后面介绍target配置 # 的时候会看到,每个target都可以覆盖定义该配置 scrape_interval: 15s # evaluation_interval指定了计算Recording Rule的时间间隔,在后续介绍的每条Recording Rule配 # 置中可以覆盖该全局配置 evaluation_interval: 15s # rule_files部分指定了定义Recording Rule的相关文件,后面讲述rule模块的时候会详细介绍# 其具体配置rule_files: # - "first.rules" # - "second.rules"# scrape_configs部分指定了Prometheus Server抓取的job信息。# Prometheus Server会在9090端口暴露自身的监控信息,在默认配置文件中会将其作为一个target进行# 抓取scrape_configs: - job_name: prometheus static_configs: - targets: ['localhost:9090']

下面执行如下命令启动Prometheus Server。./prometheus --config.file=prometheus.yml

Prometheus正常启动之后,可以访问http://localhost:9090/graph,该地址是Prometheus提供的默认查询界面,如图1-7所示。图1-7

还可以访问http://localhost:9090/metrics,该地址返回Prometheus Server状态的相关监控信息,其大致格式如图1-8所示。图1-8

感兴趣的读者可以体验一下Grafana,在安装完Grafana之后,需要将Prometheus设置成Grafana的数据源,然后就可以创建Dashboard并执行PromQL查询时序数据了。1.4 Prometheus源码环境的搭建

从Prometheus的GitHub中可以看到其中有很多项目,如图1-9所示,其中tsdb是Prometheus的本地持久化存储,alertmanager是前面介绍的告警模块,prometheus是前面介绍的Prometheus Server,pushgateway以及各种exporter项目这里没有列出。图1-9

这里以Prometheus Server的源码环境搭建为例,其他项目的环境搭建过程类似。首先是安装Golang的运行环境,这个过程比较基础,这里直接跳过。接下来执行go get命令下载Prometheus Server代码。go get github.com/prometheus/prometheus

这里使用Goland IDE阅读代码,将Prometheus Server代码导入Goland中,如图1-10所示。图1-10

之后配置main函数入口,如图1-11所示,其中File输入框需要指定main.go文件所在位置,Program arguments指定“--config.file=./prometheus.yml”命令行参数。图1-11

最后,执行go build main.go即可启动Prometheus Server。1.5 时序数据可视化

Prometheus Web UI的界面比较简单,功能也相对单一,一般只用于简单的测试。在实践中一般会使用Grafana作为Prometheus的数据可视化面板。Grafana是一个开源的可视化平台,支持多种时序数据库作为其数据源,同时也可以通过添加插件的方式扩展其功能。当前版本的Grafana已支持将Prometheus作为其数据源。

Grafana的安装非常简单,其官方网站也给出了各个系统下的详细安装方式。以macOS系统为例,使用homebrew进行安装的话,只需执行如下3条命令即可。brew updatebrew install grafanabrew services start grafana

安装完成之后,Grafana默认监听3000端口,通过地址http://localhost:3000即可进入其主页。Grafana默认的管理员账号和密码都是admin,登录之后,需要将Prometheus添加成为其数据源之一。首先找到“Data Sources”选项卡,如图1-12所示。图1-12

进入“Data Sources”页面之后,选择“Add data source”添加Prometheus类型的数据源。如图1-13所示,将URL设置为Prometheus监听的IP和端口,默认是localhost:9090。填写完成之后,可以单击“Save&Test”按钮检测Grafana是否正常访问前面启动的Prometheus实例。图1-13

完成DataSource的配置之后,回到Grafana的主页,开始添加自定义Dashboard,如图1-14所示,单击“Dashboard”。图1-14

接下来单击“New panel”以及“Add Query”创建新的查询Panel,如图1-15所示。图1-15

如图1-16所示,将Prometheus指定为新增Panel的数据源,然后添加PromQL语句即可看到时序数据。图1-16

这样,Grafana接入Prometheus数据源的基本操作就全部完成了,读者可以根据实际需求添加自定义的Panel和Dashboard。1.6 本章小结

本章首先介绍了Prometheus在时序数据库以及监控领域所处的位置,然后详细介绍了InfluxDB、Graphite、OpenTSDB以及Open-Falcon的架构特点及其优/缺点,希望读者能够通过这部分内容快速了解它们的特性,与后续介绍的Prometheus进行比较,然后根据自己的实践场景做出合适的选型。

接下来本章对Prometheus生态的核心架构和关键组件的功能进行概述,对监控数据的抓取组件、存储组件、查询功能以及告警组件等进行了简要说明。本章最后还介绍了Prometheus的安装流程、源码环境的搭建以及Grafana接入Prometheus的操作步骤,为后续深入分析Prometheus原理和实现打下基础。第2章 Prometheus配置详解

完成Prometheus的安装以及源码环境的搭建之后,本章将详细介绍prometheus.yaml配置文件中各个部分的含义和功能,这里将会以Prometheus源码中提供的demo配置文件为例进行分析,该demo配置文件的具体路径是prometheus/config/testdata/conf.good.yml。2.1 global配置

首先来看conf.good.yml配置文件中的global部分,其中定义了一些全局配置信息,例如配置两次抓取的时间间隔、抓取超时时间、计算Rule的时间周期等。在后面的每个job配置中都可以覆盖global配置。global部分的配置项如下。global: scrape_interval: 15s # 配置了Prometheus抓取target的时间间隔,默认值1min抓取一次 scrape_timeout: 10s # 抓取target的超时时间,默认值为10s evaluation_interval: 30s # 指定Prometheus计算一个Rule配置的时间间隔 # 在外部系统进行传输时,会将external_labels中指定的Label添加到时序上,前提是 # 时序上没有冲突Label,如果存在冲突的Label,则不会添加该配置中的Label。 external_labels: monitor: codelab foo: bar2.2 scrape_config基础配置

接下来看scrape_config部分,其中可以定义多个job项,但一般情况下,每个scrape_config下只配置一个job。可以在每个job中自定义抓取周期和超时时间,这些自定义配置会覆盖上面介绍的global全局配置。在一个job中可以配置多个抓取地址(HTTP URL)、抓取时的http参数以及这些target的公共Label等信息。下面是scrape_config部分中比较重要的几个配置项。scrape_configs:# job名称,Prometheus会将该名称作为Label追加到抓取的每条时序中- job_name: prometheus # 这里的scrape_interval和scrape_timeout配置会覆盖global部分的同名配置,且只对该job生效 scrape_interval: 1m scrape_timeout: 5s metrics_path: /metrics # 抓取时序数据的http path,默认值为/metrics scheme: http # 抓取时序数据时使用的网络协议,默认是http # 抓取时序数据时,请求携带的相关参数 params: test: test

下面将要介绍的是job配置项下相对比较复杂的配置项。2.2.1 static_configs配置

在static_configs部分中,可以通过静态方式配置该job要抓取的target地址,每个地址对应一个target。另外,在static_configs下还可以为这些target配置公共的Label,从上述targets抓取到的全部时序都会被添加进这些公共Label。下面是static_configs部分的配置示例。 # 用静态方式配置该job要抓取的地址,每个地址对应一个target static_configs: - targets: ['localhost:9090','localhost:9191'] labels: # 上述target的公共Label,从上述targets抓取到的全部时序都会被追加进这些公共Label my: label your: label2.2.2 file_sd_configs配置

Prometheus Server除了通过static_configs配置target的地址之外,还可以通过服务发现的方式获取target的地址。这里以基于文件的服务发现方式进行介绍,可以将target的配置信息写入单独的JSON或YAML配置文件中,然后将这些配置文件添加到file_sd_configs配置项中,Prometheus Server会定期检测这些文件是否变化,若发生变化,则会重新配置target信息。同时,Prometheus Server也会定期全量加载这些配置文件中的target信息。下面是file_sd_configs配置项的示例。# 重新加载file_sd_configs: - files: # 下面的文件中配置了相关的target信息 - foo/*.slow.json - foo/*.slow.yml - single/file.yml refresh_interval: 10m # Prometheus每隔10min会重新加载上述配置文件,更新其target信息2.2.3 其他服务发现

除了基于文件的服务发现之外,Prometheus还支持多种常见的服务发现组件,例如Kubernetes、DNS、ZooKeeper、Consul、Azure、EC2和GCE等,这里不再一一列举对应的配置项,感兴趣的读者可以参考Prometheus官方文档。2.2.4 honor_labels配置

honor_labels配置项决定Prometheus如何处理时序数据中出现的Label冲突。例如,某个时序中已经包含了job这个Label,而Prometheus 默认会将target在配置中对应的job_name信息追加到时序数据中作为job Label,这样两者就产生了冲突。如果honor_labels配置项的取值不同,则Prometheus处理这种冲突的行为也会有所不同。● 若honor_labels被设置为true,则会保留时序原有的Label,忽略

Prometheus Server端追加的冲突Label。● 若honor_labels被设置为false,则在时序原有的Label Name前追

加“exported_”标识。例如前面示例中的“job”就会被改写成“exported_job”,Prometheus Server端追加的Label不变。

另外,external_labels配置项中定义的Label并不会受该配置的影响。

honor_labels配置项的示例如下。honor_labels: true2.2.5 relabel_configs配置

relabel_configs部分主要用于配置Prometheus的Relabel操作,Relabel操作的主要目的是修改Label信息。在Prometheus中有多个核心方法会触发Relabel操作。

这里简单介绍一下加载target配置信息流程涉及的Relabel操作,在其触发Relabel操作之前,Prometheus会做如下准备工作。● 将每条时序的job Label的value值设置成配置文件中指定的

job_name值。● 将__address__ label的value值设置成target的:。● 将__scheme__ label的value值设置成配置文件中指定的scheme

值。● 将__metrics_path__ label的value值设置成配置文件中指定的

metrics_path值。● 将__param_ label的value值设置成配置文件中指定的

params值。● 添加以__meta_为前缀的Label信息,使用不同的服务发现机制,

对应添加的Label信息会有所不同。

默认情况下,如果Label Name以“__”开头,则该Label是Prometheus内部使用的。例如,后面深入分析scrape模块时可以看到,其中的target结构体就记录了__address__ label等内部Label,通过这些Label即可在抓取操作中获取target的URL地址。这些内部Label不会持久化到时序数据中,用户通过PromQL查询时序数据时是察觉不到这些Label的存在的。

但是,可以利用这些内部的Label实现一些需求,如果时序的Label集合中不包含instance label,则Prometheus默认会将__address__ label的value值设置成instance label的value值,这其实与用户自定义的Relabel操作一样。

现在回到relabel_configs配置项,在relabel_config部分可以配置多个Relabel操作,而且这些Relabel操作是顺序执行的。如果一个Relabel操作需要产生临时Label给下一个Relabel操作使用,则一般会用“__tmp_”作为Label Name的前缀。临时Label类似编程语言中的临时变量,不会追加到时序数据中。

下面是relabel_configs配置的示例。relabel_configs: # source_labels配置指定了参与该Relabel操作的Label Name,如果指定多个Label Name, # 默认按照逗号分割- source_labels: [job,__meta_dns_name] # regex配置了一个正则表达式,只有符合该正则的Label Value,才能被该Relabl操作处理 regex:(.*)some-[regex] # 经过该Relabel操作处理的Label Value值会被写入target_label指定的Label中 target_label: job # 如果Label Value符合regex指定的正则,则会被替换成replacement指定的格式, # 其中$1即为原Label Value replacement: foo-${1} # action defaults to 'replace'- source_labels: [job] regex: (.*)some-[regex] action: drop # 如果Label Value符合RelabelConfig指定的正则表达式,则过滤掉该时序- source_labels: [__address__] modulus: 8 target_label: __tmp_hash # 计算参与Relabel操作的Label Value的hash值并取模,然后生成新的Label记录该计算结果 action: hashmod - source_labels: [__tmp_hash] regex: 1 action: keep # 如果Label Value不符合RelabelConfig指定的正则表达式,则过滤掉该时序 # 匹配全部Label Name,符合指定正则表达式的Label Name会根据指定的模板生成新的Label Name, # 此过程中的Label Value不变- action: labelmap replacement: k-${1} regex: 1- action: labeldrop # 如果Label Name符合指定的正则表达式,则将该Label删除 regex: d- action: labelkeep # 如果Label Name不符合指定的正则表达式,则将该Label删除 regex: k

这里简单介绍了Relabel操作中各个action的含义,在后面介绍Relabel操作的具体实现代码时,还会更加详细地分析这些action的功能。

到此为止,scrape_config部分常用且核心的配置项就介绍完了。2.3 Rule的相关配置

在第1章中提到, Prometheus支持用户自定义Rule规则。 Rule分为两类,一类是Recording Rule,另一类是Alerting Rule。Recording Rule的主要目的是预先计算那些比较复杂的、执行时间较长的PromQL语句,并将其执行结果保存成一条单独的时序,后续查询时直接返回该结果即可。通过Recording Rule这种优化方式可以降低Prometheus的响应时间。

在rule_files配置项中可以指定Rule配置文件的位置,其配置如下。rule_files:- "first.rules"- "my/*.rules"

在Recording Rule配置文件中,可以包含多个Rule Group配置,而一个Rule Group下可以包含多个Recording Rule配置,下面是Recording Rule配置文件的简单示例。groups: - name: test # Rule Group的名称 interval: 30s # 该组Rule的计算周期,该配置会覆盖global中的 evaluation_interval配置 rules: # 可以定义多条Recording Rule - record: "new_metric" # Record Rule的名称,其实就是metric名称 # PromQL语句 expr: | sum without(instance)(rate(errors_total[5m])) / sum without(instance)(rate(requests_total[5m])) labels: # 该配置项中的Label将会被追加到新生成的时序中,如果出现Label冲突,则会进行覆盖 abc: edf

Alerting Rule的主要目的是进行告警的判定。Alerting Rule会定义一条PromQL语句,然后定时执行该PromQL语句并根据执行结果判断是否触发告警。Alerting Rule配置文件与Record Rule配置文件相同,也需要添加到rule_files配置项下才能被Prometheus加载。

Alerting Rule配置文件的具体内容与Recording Rule类似,可以包含多个Rule Group配置,同时一个Rule Group下可以包含多个Alerting Rule配置,但是具体的配置项有细微差别。下面是Alerting Rule配置文件的简单实例。groups: - name: example # Rule Group的名称 interval: 30s # 该组Rule的计算周期,与Recording Rule配置相同,会覆盖全局配置 rules: - alert: HighErrorRate # 告警名称 # PromQL语句,Alerting Rule通过该PromQL告警触发条件,其计算结果表示是否满足触发告警的条件 expr: job:request_latency_seconds:mean5m{job="myjob"} > 0.5 for: 10m # 告警触发的等待时间,只有告警条件被触发的持续时间超过这里配置的时长,才会真正

试读结束[说明:试读内容隐藏了图片]

下载完整电子书

若在网站上没有找合适的书籍,可联系网站客服获取,各类电子版图书资料皆有。

客服微信:xzh432

登入/注册
卧槽~你还有脸回来
没有账号? 忘记密码?