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.  架构:

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

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(记法) 

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

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

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

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:<host>:<port>是被抓取的目标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 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 # 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/

 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 "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的所有时间序列:

 http_requests_total

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

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

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

标签匹配操作符:

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

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

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

不要匹配空标签

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

3.3.4.  范围向量选择器

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

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

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

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

Offset修饰符

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

 http_requests_total offset 5m 

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

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

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

 rate(http_requests_total[5m] offset 1w)

3.3.5.  子查询

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

3.3.5.  运算符 

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

算术二元运算符

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

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

比较二元运算符

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

逻辑运算符

and 、or 、unless

聚合运算符

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

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

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

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

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 # 返回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数据源,接着创建面板并定义查询的指标

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

 

 

https://prometheus.io/docs/introduction/overview/

https://prometheus.io/docs/alerting/overview/ 

 

posted @ 2019-09-27 09:25  废物大师兄  阅读(18072)  评论(1)    收藏  举报