Prometheus入门

简介

转载于:5分钟了解Prometheus

Prometheus(译:普罗米修斯)用领先的开源监控解决方案为你的指标和警报提供动力(赋能)。

1. 概述

1.1. Prometheus是什么?

Prometheus是一个开源的系统监控和警报工具包。自2012年启动以来,许多公司和组织都采用了Prometheus,该项目拥有非常活跃的开发人员和用户社区。它现在是一个独立的开源项目,独立于任何公司进行维护。Prometheus于2016年加入云原生计算基金会,成为继Kubernetes之后的第二个托管项目。

1.1.1. Prometheus的主要特性:

  • 一个多维数据模型,包含由指标名称和键/值对(Tag)标识的时间序列数据
  • PromQL是一种灵活的查询语音,用于查询并利用这些维度数据
  • 不依赖分布式存储,单个服务器节点是自治的
  • 时间序列收集是通过HTTP上的pull模型进行的(支持Pull)
  • 推送时间序列是通过一个中间网关来支持的(也支持Push)
  • 目标是通过服务发现或静态配置发现的
  • 多种模式的图形和仪表盘支持

总结一下,就是多维数据模型、PromQL查询语言、节点自治、HTTP主动拉取或者网关主动推送的方式获取时间序列数据、自动发现目标、多种仪表盘支持

1.1.2. 组件:

  • Prometheus server,它负责抓取和存储时间序列数据,是最主要的组件
  • client libraries,用于检测应用程序代码的客户端库
  • push gateway,用于支持短期的jobs
  • exporters,用于支持HAProxy等第三方
  • alertmanager,用于处理告警
  • 各种支持工具

大多数Prometheus组件都是用Go编写的,这使得它们易于作为静态二进制文件构建和部署

1.1.3. 架构:

这张图展示了架构及其生态系统的一些组成部分:

img

Prometheus从工具化的作业中获取指标,要么直接获取,要么通过中介推送网关获取短期作业。它在本地存储所有抓取的样本,并对这些数据应用规则将这些数据进行聚合,并记录新的时间序列,或者生成警报。可以用Grafana或其他API来可视化收集的数据。

1.2. 什么时候用它合适

Prometheus可以很好地记录任何纯数字时间序列。它既适合以机器为中心的监视,也适合高度动态的面向服务的体系结构的监视。在微服务的世界中,它对多维数据收集和查询的支持是一个特别的优势。

Prometheus是为可靠性而设计的,在你的服务宕机的时候,你可以快速诊断问题。每台Prometheus服务器都是独立的,不依赖于网络存储或其他远程服务。

1.3. 什么时候用它不合适

Prometheus的值的可靠性。你总是可以查看有关系统的统计信息,即使在出现故障的情况下也是如此。如果你需要100%的准确性,例如按请求计费,Prometheus不是一个好的选择,因为收集的数据可能不够详细和完整。在这种情况下,最好使用其他系统来收集和分析用于计费的数据,并使用Prometheus来完成剩下的监视工作。

1.4. Prometheus VS InfluxDB

InfluxDB是一个开源的时间序列数据库,具有扩展和集群的商业选项。InfluxDB项目是在Prometheus开发开始将近一年后发布的,所以当时无法考虑将其作为替代方案。尽管如此,Prometheus和fluxdb之间仍然存在显著的差异。二者有许多相似之处。两者都有标签(在InfluxDB中称为tags)来有效地支持多维度度量。它们基本上使用相同的数据压缩算法。两者都具有广泛的集成,包括彼此之间的集成。两者都有挂钩,允许进一步扩展它们,例如在统计工具中分析数据或执行自动化操作。

下列情况,用InfluxDB更好:

  • 如果你正在进行事件日志记录
  • 商业选项为InfluxDB提供集群,这对于长期数据存储也更好
  • 最终实现副本之间数据的一致性

下列情况,用Prometheus更好:

  • 如果你主要做的是度量
  • 如果你需要更强大的查询语言、警报和通知功能
  • 更高的可用性和正常运行时间,用于绘图和报警

InfluxDB由一家遵循开放核心模型的商业公司维护,提供高级特性,如闭源集群、托管和支持。

Prometheus是一个完全开源和独立的项目,由许多公司和个人维护,其中一些还提供商业服务和支持。

2. 基本概念

2.1. 数据模型

Prometheus基本上将所有数据存储为时间序列:属于同一指标和同一组标记维度的时间戳值流。除了存储时间序列外,Prometheus还可以根据查询结果生成临时派生的时间序列。

(PS:这里对时间序列的解释是这样的,time series: streams of timestamped values belonging to the same metric and the same set of labeled dimensions)

2.1.1. Metric names and labels

Every time series is uniquely identified by its metric name and optional key-value pairs called labels.

(每个时间序列都由其指标名称和称为标签的可选键值对唯一标识)

指标名称指定要度量的系统的一般特性(例如,http_requests_total表示接收的HTTP请求的总数)。它可能包含ASCII字母和数字,以及下划线和冒号。它必须匹配正则表达式[a-zA-Z_:][a-zA-Z0-9_:]*

标签名称可以包含ASCII字母、数字和下划线。它们必须匹配正则表达式[a-zA-Z_][a-zA-Z0-9_]*。以__开头的标签名称保留内部使用。

标签值可以包含任何Unicode字符。

2.1.2. Sample(样本)

样本构成实际的时间序列数据。每个样本包括:

  • a float64 value
  • a millisecond-precision timestamp

2.1.3. notation(记法)

给定一个度量名称和一组标签,时间序列通常使用以下符号标识:

1
<metric name>{<label name>=<label value>,...}

例如,有这样一个时间序列,指标名称是api_http_requests_total,有两个标签method=”POST”和handler=”/messages”,那么这个时间序列可以这样写:

1
api_http_requests_total{method="POST", handler="/messages"}

2.2. metric types(指标类型)

2.2.1. Counter(计数器)

计数器是一个累积指标,它表示一个单调递增的计数器,其值只能在重启时递增或重置为零。例如,可以使用计数器来表示已服务的请求数、已完成的任务数或错误数。不要使用计数器来反映一个可能会减小的值。例如,不要使用计数器表示当前正在运行的进程的数量,这种情况下,你应该用gauge。

2.2.2. Gauge(计量器)

计量器表示一个可以任意上下移动的数值。

计量器通常用于测量温度或当前内存使用量等,也用于“计数”,比如并发请求的数量。

2.2.3. Histogram(直方图、柱状图)

直方图对观察结果(通常是请求持续时间或响应大小之类的东西)进行采样,并在可配置的桶中计数。它还提供了所有观测值的和。

直方图用一个基本的指标名<basename>暴露在一个抓取期间的多个时间序列:

  • 观察桶的累积计数器,格式为<basename>_bucket{le="<upper inclusive bound>"}
  • 所有观测值的总和,格式为<basename>_sum
  • 已观察到的事件的计数,格式为<basename>_count

2.2.4. Summary(摘要)

与柱状图类似,摘要样例观察结果(通常是请求持续时间和响应大小之类的内容)。虽然它还提供了观测值的总数和所有观测值的总和,但它计算了一个滑动时间窗口上的可配置分位数。

2.3. Jobs AND Instances(作业与实例)

在Prometheus的术语中,可以抓取的端点称为实例,通常对应于单个进程。具有相同目的的实例集合称为作业。

例如,一个API Server job 有4个副本instances:

job: api-server

  • instance 1: 1.2.3.4:5670
  • instance 2: 1.2.3.4:5671
  • instance 3: 5.6.7.8:5670
  • instance 4: 5.6.7.8:5671

2.3.1. 自动生成标签和时间序列

当Prometheus抓取目标时,它会自动在抓取的时间序列上附加一些标签,用来识别被抓取的目标:

  • job:目标所属的已配置作业名称
  • instance::是被抓取的目标URL的一部分

3. 快速开始

Prometheus是一个开源的系统监控和警报工具包,具有活跃的生态系统。

3.1. 下载与安装

Prometheus是一个监控平台,它通过抓取这些目标上的HTTP端点来收集被监控目标的指标。

需要下载、安装并运行Prometheus。还需要下载并安装一个exporter,它是将主机和服务上的时间序列数据导出的工具。https://prometheus.io/download/

在运行Prometheus之前,我们先配置一下

3.1.1. 配置Prometheus监视它自己

Prometheus通过抓取目标上的HTTP端点数据来从被监控的目标收集数据。由于Prometheus也以同样的方式公开自己的数据,因此它还可以抓取和监测自己的健康状况。

虽然Prometheus服务器在实践中只收集关于自己的数据不是很有用,但是它是一个很好的开始示例。将以下基本的Prometheus配置保存为一个名为Prometheus.yml的文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 1 global:
2 scrape_interval: 15s # By default, scrape targets every 15 seconds.
3
4 # Attach these labels to any time series or alerts when communicating with
5 # external systems (federation, remote storage, Alertmanager).
6 external_labels:
7 monitor: 'codelab-monitor'
8
9 # A scrape configuration containing exactly one endpoint to scrape:
10 # Here it's Prometheus itself.
11 scrape_configs:
12 # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
13 - job_name: 'prometheus'
14
15 # Override the global default and scrape targets from this job every 5 seconds.
16 scrape_interval: 5s
17
18 static_configs:
19 - targets: ['localhost:9090']

3.1.2. 启动Prometheus

1
2
3
1 # Start Prometheus.
2 # By default, Prometheus stores its database in ./data (flag --storage.tsdb.path).
3 ./prometheus --config.file=prometheus.yml

3.2. 配置

Prometheus可以通过命令行和配置文件进行配置。配置文件定义了与抓取作业及其实例相关的所有内容,以及要加载哪些规则文件。

运行./prometheus -h可以查看所有支持的命令

为了指定要加载哪个配置文件,请使用--config选项

配置文件是YAML格式的。配置项太多,不一一列举,自行查看https://prometheus.io/docs/prometheus/latest/configuration/configuration/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
global:
# How frequently to scrape targets by default.
[ scrape_interval: <duration> | default = 1m ]

# How long until a scrape request times out.
[ scrape_timeout: <duration> | default = 10s ]

# How frequently to evaluate rules.
[ evaluation_interval: <duration> | default = 1m ]

# The labels to add to any time series or alerts when communicating with
# external systems (federation, remote storage, Alertmanager).
external_labels:
[ <labelname>: <labelvalue> ... ]

# Rule files specifies a list of globs. Rules and alerts are read from
# all matching files.
rule_files:
[ - <filepath_glob> ... ]

# A list of scrape configurations.
scrape_configs:
[ - <scrape_config> ... ]

# Alerting specifies settings related to the Alertmanager.
alerting:
alert_relabel_configs:
[ - <relabel_config> ... ]
alertmanagers:
[ - <alertmanager_config> ... ]

# Settings related to the remote write feature.
remote_write:
[ - <remote_write> ... ]

# Settings related to the remote read feature.
remote_read:
[ - <remote_read> ... ]

3.3. 查询

Prometheus提供了一种名为PromQL(Prometheus查询语言)的函数式查询语言,允许用户实时选择和聚合时间序列数据。表达式的结果既可以显示为图形,也可以在Prometheus的表达式浏览器中作为表格数据查看,或者通过HTTP API由外部系统使用。

3.3.1. 表达式数据类型

在Prometheus的表达式语言中,表达式或子表达式可以计算为以下四种类型之一:

  • Instant vector(瞬时向量):一组时间序列,每个时间序列包含一个样本,所有样本共享相同的时间戳
  • Range vector(范围向量):一组时间序列,其中包含每个时间序列随时间变化的数据点范围
  • Scalar(标量):一个简单的数值浮点值
  • String(字符串):一个简单的字符串值,目前未使用

3.3.2. 字面值

字符串字面值

字符串可以指定为单引号、双引号或反引号中的文字。例如:

1
2
3
1 "this is a string"
2 'these are unescaped: \n \\ \t'
3 `these are not unescaped: \n ' " \t`

浮点数字面值

例如:-2.34

3.3.3. 时间序列选择器

瞬时向量选择器

瞬时向量选择器允许在给定的时间戳(瞬时)上为每个时间序列选择一组时间序列和一个样本值:在最简单的形式中,只指定一个度量名称。这样一个向量就会包含这个度量名称的所有时间序列元素。

下面的例子,选择指标名称是http_requests_total的所有时间序列:

1
http_requests_total

通过在花括号({ })中添加一组匹配的标签,可以进一步过滤这些时间序列。

下面的例子,选择指标名称是http_requests_total,并且有job标签值是prometheus,并且group标签值是canary的时间序列:

1
http_requests_total{job="prometheus",group="canary"} 

标签匹配操作符:

  • = : 选择与提供的字符串完全相同的标签(等于)
  • != :选择不等于提供的字符串的标签(不等于)
  • =~ :正则匹配
  • !~ : 非正则匹配

下面的例子,选择所有staging, testing, development环境,并且HTTP请求方式不是GET的http_requests_total时间序列

1
http_requests_total{environment=~"staging|testing|development",method!="GET"} 

不要匹配空标签

1
2
{job=~".+"}              # Good!
{job=~".*",method="get"} # Good!

3.3.4. 范围向量选择器

范围向量字面量的工作原理与瞬时向量字面量类似,只是它们从当前瞬时量中选择一个样本范围。从语法上讲,范围持续时间被添加到向量选择器末尾的方括号([ ])中,以指定应该为每个结果范围向量元素获取多少时间值。

时间期限指定为一个数字,紧接其后的是下列单位之一:s(秒)、m(分钟)、h(小时)、d(天) 、w(周)、y(年)

下面的例子,选择指标名是http_requests_total,且job标签值是prometheus的已经记录的最近5分钟内的时间序列:

1
http_requests_total{job="prometheus"}[5m]

Offset修饰符

下面的表达式返回http_requests_total在过去5分钟相对于当前查询计算时间的值:

1
http_requests_total offset 5m 

注意,offset总是紧跟在选择器后面的

1
sum(http_requests_total{method="GET"} offset 5m) 

下面的例子,返回一周前的最近5分钟http_requests_total的时间序列

1
rate(http_requests_total[5m] offset 1w)

3.3.5. 子查询

1
Syntax: <instant_query> '[' <range> ':' [<resolution>] ']' [ offset <duration> ]

3.3.6. 运算符

Prometheus的查询语言支持基本的逻辑运算符和算术运算符。

算术二元运算符

+(加)、-(减)、*(乘)、/(除)、%(余数)、^(指数)

二进制算术运算符定义在标量/标量、向量/标量和向量/向量值对之间

比较二元运算符

== 、!= 、> 、< 、>= 、<=

逻辑运算符

and 、or 、unless

聚合运算符

sum(求和)、min(最小值)、max(最大值)、avg(求平均)、stddev(标准偏差)、stdvar(方差)、count(个数)、count_values(相同值的元素个数)、bottomk(样本值的最小元素)、topk(样本值的最大元素)、quantile(0 ≤ φ ≤ 1)

这些操作符既可以用于聚合所有标签维度,也可以通过包含without子句或by子句来保存不同的维度。

1
1 <aggr-op>([parameter,] <vector expression>) [without|by (<label list>)]

例如,假设http_requests_total有application 、 instance 、 group三个标签,那么下面两个是等价的:

1
2
1 sum(http_requests_total) without (instance)
2 sum(http_requests_total) by (application, group)

3.3.6. 函数

https://prometheus.io/docs/prometheus/latest/querying/functions/

3.3.7. 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 1 # 返回http_requests_total的所有时间序列
2 http_requests_total
3
4 # 返回http_requests_total的且限定了job和handler标签的时间序列
5 http_requests_total{job="apiserver", handler="/api/comments"}
6 http_requests_total{job="apiserver", handler="/api/comments"}[5m]
7
8 # 正则表达式
9 http_requests_total{job=~".*server"}
10 http_requests_total{status!~"4.."}
11
12 # 过去的5分钟内每秒HTTP请求速率
13 rate(http_requests_total{job="api-server"}[5m])
14 # 过去的30分钟内每5分钟
15 rate(http_requests_total[5m])[30m:1m]
16 # 过去5分钟的所有请求速率求和,保留job维度
17 sum(rate(http_requests_total[5m])) by (job)
18 # cpu使用率最高的前3个
19 topk(3, sum(rate(instance_cpu_time_ns[5m])) by (app, proc))

4. Grafana支持

Grafana支持查询Prometheus

下面是Grafana dashboard查询Prometheus数据的例子:

默认情况下,Grafana监听http://localhost:3000,默认用admin/admin登录

创建一个Prometheus数据源,接着创建面板并定义查询的指标

img

img

img

img

img

刚开始,如果不知道PromeQL怎么写,可以去Prometheus上去找 http://localhost:9090/graph

img

img

img

一分一毛,也是心意。