Prometheus

493 阅读9分钟

  SoundCloud 开源监控告警解决方案。

songjiayang.gitbooks.io/prometheus

1. 主要功能

  多维数据模型(时序由 metric 名字和 k/v 的 labels 构成)。
  灵活的查询语句 PromQL
  无依赖存储,支持 local 和 remote 不同模型。
  采用 http 协议,使用 pull 模式,拉取数据。
  监控目标,可以采用服务发现或静态配置的方式。
  支持多种统计数据模型。

2. 核心组件

  Prometheus Server 主要用于抓取数据和存储时序数据,另外还提供查询和 Alert Rule 配置管理。
  client libraries 用于对接 Prometheus Server, 可以查询和上报数据。
  push gateway 用于批量,短期的监控数据的汇总节点,主要用于业务数据汇报等。
  汇报数据的 exporters ,例如汇报机器数据的 node_exporter, 汇报 MongoDB 信息的 MongoDB exporter 等等。
  用于告警通知管理的 alertmanager

3. 架构

image

  模块主要包含 Server Exporters Pushgateway PromQL Alertmanager WebUI 等。

逻辑

  1. Prometheus server 定期从静态配置的 targets 或者服务发现的 targets 拉取数据。
  2. 当新拉取的数据大于配置内存缓存区的时候,Prometheus 会将数据持久化到磁盘(如果使用 remote storage 将持久化到云端)。
  3. Prometheus 可以配置 rules,然后定时查询数据,当条件触发的时候,会将 alert 推送到配置的 Alertmanager。
  4. Alertmanager 收到警告的时候,可以根据配置,聚合,去重,降噪,最后发送警告。
  5. 可以使用 API,Prometheus Console 或者 Grafana 查询和聚合数据。
  • Prometheus 的数据是基于时序的 float64 的值,如果你的数据值有更多类型,无法满足。
  • Prometheus 不适合做审计计费,因为它的数据是按一定时间采集的,关注的更多是系统的运行瞬时状态以及趋势,即使有少量数据没有采集也能容忍,但是审计计费需要记录每个请求,并且数据长期存储,这个Prometheus 无法满足,可能需要采用专门的审计系统。

4. 对比

优点

  • 一站式 监控告警平台,依赖少,功能齐全。

  • 云或容器监控 其他系统主要对主机监控。

  • 数据查询 语句表现力更强大,内置更强大的统计函数。

缺点

  数据存储扩展性以及持久性上没有 InfluxDB,OpenTSDB,Sensu 好。

VS Zabbix

  Zabbix 使用的是 C 和 PHP ,Prometheus 使用 Golang ,整体而言 Prometheus 运行速度更快一点。Zabbix 属于传统主机监控,主要用于物理主机,交换机,网络等监控,Prometheus 不仅适用主机监控,还适用于 Cloud SaaS Openstack Container 监控。Zabbix 在传统主机监控方面,有更丰富的插件。Zabbix 可以在 WebGui 中配置很多事情,但是 Prometheus 需要手动修改文件配置

VS Graphite

  Graphite 功能较少,它专注于两件事,存储时序数据,可视化数据,其他功能需要安装相关插件,而 Prometheus 属于一站式,提供告警和趋势分析的常见功能,它提供更强的数据存储和查询能力。Graphite 在水平扩展方案以及数据存储周期上做的更好。

VS InfluxDB

  InfluxDB 是一个开源的时序数据库,主要用于存储数据,如果想搭建监控告警系统, 需要依赖其他系统。InfluxDB 在存储水平扩展以及高可用方面做的更好,毕竟核心是数据库。

VS OpenTSDB

  OpenTSDB 是一个分布式时序数据库,它依赖 Hadoop 和 HBase,能存储更长久数据, 如果你系统已经运行了 Hadoop 和 HBase, 它是个不错的选择。如果想搭建监控告警系统,OpenTSDB 需要依赖其他系统。

VS Nagios

  Nagios 数据不支持自定义 Labels,不支持查询,告警也不支持去噪,分组, 没有数据存储,如果想查询历史状态,需要安装插件。Nagios 是上世纪 90 年代的监控系统,比较适合小集群或静态系统的监控,显然 Nagios 太古老了,很多特性都没有,相比之下Prometheus 要优秀很多。

VS Sensu

  Sensu 广义上讲是 Nagios 的升级版本,它解决了很多 Nagios 的问题,如果你对 Nagios 很熟悉,使用 Sensu 是个不错的选择。Sensu 依赖 RabbitMQ 和 Redis,数据存储上扩展性更好。

5. 数据模型

  Prometheus 存储的是时序数据,即按照相同时序(相同的名字和标签),以时间维度存储连续的数据的集合。

时序索引

  时序 time series  是由名字 Metric ,以及一组 key/value 标签定义的,具有相同的名字以及标签属于相同时序。时序的名字由 ASCII 字符,数字,下划线,以及冒号组成,它必须满足正则表达式 [a-zA-Z_:][a-zA-Z0-9_:]*,其名字应该具有语义化,一般表示一个可以度量的指标,例如: http_requests_total, 可以表示 http 请求的总数。时序的标签能够区分具体不同的实例,例如 http_requests_total{method="POST"} 可以表示所有 http 中的 POST 请求。标签名称由 ASCII 字符,数字,以及下划线组成, 其中 __ 开头属于 Prometheus 保留,标签的值可以是任何 Unicode 字符,支持中文。

时序样本

  按照某个时序以时间维度采集的数据,称之为样本,其值包含:一个 float64 值 & 一个毫秒级的 unix 时间戳。

格式

  Prometheus 时序格式与 OpenTSDB 相似: <metric name>{<label name>=<label value>, ...} 其中包含时序名字以及时序的标签。

6. 时序类型

  Counter Gauge Histogram Summary 四种类型。

6.1. Counter

  收集的数据是按照某个趋势(增加/减少)一直变化的,往往用于记录服务请求总量、错误总数等。例如: Prometheus server 中 http_requests_total , 表示 Prometheus 处理的 http 请求总数,我们可以使用 delta ,很容易得到任意区间数据的增量,这个会在 PromQL 一节中细讲。

6.2. Gauge 

  搜集的数据是一个瞬时的值,与时间没有关系,可以任意变高变低,往往可以用来记录内存使用率、磁盘使用率等。例如 Prometheus server 中 go_goroutines, 表示 Prometheus 当前 goroutines 的数量。

6.3. Histogram 

  Histogram 由 <basename>_bucket{le="<upper inclusive bound>"}<basename>_bucket{le="+Inf"}, <basename>_sum<basename>_count 组成,主要用于表示一段时间范围内对数据进行采样(通常是请求持续时间或响应大小),并能够对其指定区间以及总数进行统计,通常它采集的数据展示为直方图。例如 Prometheus server 中 prometheus_local_storage_series_chunks_persisted, 表示 Prometheus 中每个时序需要存储的 chunks 数量,我们可以用它计算待持久化的数据的分位数。

6.4. Summary 

  Summary 和 Histogram 类似,由 <basename>{quantile="<φ>"}<basename>_sum<basename>_count 组成,主要用于表示一段时间内数据采样结果(通常是请求持续时间或响应大小),它直接存储了 quantile 数据,而不是根据统计区间计算出来的。例如 Prometheus server 中 prometheus_target_interval_length_seconds

6.5. Histogram vs Summary 

  • 都包含 <basename>_sum<basename>_count
  • Histogram 需要通过 <basename>_bucket 计算 quantile, 而 Summary 直接存储了 quantile 的值。

7. PromQL

  PromQL (Prometheus Query Language) 是 Prometheus 自己开发的数据查询 DSL 语言,数据可视化以及 rule 告警会使用到它。在页面 http://localhost:9090/graph 中,输入下面的查询语句,查看结果,例如:

http_requests_total{code="200"}

  字符串 往往作为查询条件 labels 的值,和 Golang 字符串语法一致,可以使用 "" '' ``正数 浮点数

7.1. 结果类型

  瞬时数据  (Instant vector)包含一组时序,每个时序只有一个点,例如:http_requests_total
  区间数据  (Range vector)包含一组时序,每个时序有多个点,例如:http_requests_total[5m]
  纯量数据  (Scalar)纯量只有一个数字,没有时序,例如:count(http_requests_total)

7.2. 查询条件

  Prometheus 存储的是时序数据,而它的时序是由名字和一组标签构成的,其实名字也可以写出标签的形式,例如 http_requests_total 等价于 {name="http_requests_total"} 。一个简单的查询相当于是对各种标签的筛选,例如:

http_requests_total{code="200"}     // 查询名字为 http_requests_total,code 为 "200" 的数据

  查询条件支持正则匹配,例如:

http_requests_total{code!="200"}  // 表示查询 code 不为 "200" 的数据 http_requests_total{code=~"2.."} // 模糊查询 code 为 "2xx" 的数据 http_requests_total{code!~"2.."} // 表示查询 code 不为 "2xx" 的数据

7.3. 操作符

  Prometheus 查询语句中,支持常见的各种表达式操作符,例如

算术运算符

  支持的算术运算符有 +,-,*,/,%,^, 例如 http_requests_total * 2 表示将 http_requests_total 所有数据 double 一倍。

比较运算符

  支持的比较运算符有 ==,!=,>,<,>=,<=, 例如 http_requests_total > 100 表示 http_requests_total 结果中大于 100 的数据。

逻辑运算符

  支持的逻辑运算符有 and  or  unless, 例如 http_requests_total == 5 or http_requests_total == 2 表示 http_requests_total 结果中等于 5 或者 2 的数据。

聚合运算符

  支持的聚合运算符有 sum min max  avg  stddev  stdvar  count  count_values  bottomk  topk  quantil 例如:max(http_requests_total) 表示 http_requests_total 结果中最大的数据。注意,和四则运算类型,Prometheus 的运算符也有优先级,它们遵从 (^) > (*, /, %)  > (+, -) > (==, !=, <=, <, >=, >)  > (and, unless)  > (or) 的原则。

7.4. 内置函数

  Prometheus 内置不少函数,方便查询以及数据格式化,例如将结果由浮点数转为整数的 floor 和 ceil:

floor(avg(http_requests_total{code="200"}))
ceil(avg(http_requests_total{code="200"}))

  查看 http_requests_total 5分钟内,平均每秒数据:

rate(http_requests_total[5m])

8. Web

Web界面

http://localhost:9090/graph

集成Grafana

grafana.com/grafana/dow…

9. 配置

  全局配置(global) 告警配置(alerting) 规则配置(rule_files) 数据拉取配置(scrape_configs) 远程可写存储(remote_write) 远程可读存储(remote_read)  

songjiayang.gitbooks.io/prometheus/…

9.1. 服务发现

  数据源 target 配置主要分为静态配置和动态发现, 大致为以下几类:

  • static_configs 静态服务发现
  • dns_sd_configs DNS 服务发现
  • file_sd_configs 文件服务发现
  • consul_sd_configs Consul 服务发现
  • serverset_sd_configs Serverset 服务发现
  • nerve_sd_configs Nerve 服务发现
  • marathon_sd_configs Marathon 服务发现
  • kubernetes_sd_configs Kubernetes 服务发现
  • gce_sd_configs GCE 服务发现
  • ec2_sd_configs EC2 服务发现
  • openstack_sd_configs OpenStack 服务发现
  • azure_sd_configs Azure 服务发现
  • triton_sd_configs Triton 服务发现

  使用最广泛为 static_configs ,其他动态类型都可以看成是某些通用业务使用静态服务封装的结果。

9.2. 示例 

global:
  scrape_interval:     15s # By default, scrape targets every 15 seconds.
  evaluation_interval: 15s # By default, scrape targets every 15 seconds.

rule_files:
  - "rules/node.rules"

scrape_configs:
  - job_name: 'prometheus'
    scrape_interval: 5s
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'node'
    scrape_interval: 8s
    static_configs:
      - targets: ['127.0.0.1:9100', '127.0.0.12:9100']

  - job_name: 'mysqld'
    static_configs:
      - targets: ['127.0.0.1:9104']
      
  - job_name: 'memcached'
    static_configs:
      - targets: ['127.0.0.1:9150']

10. Exporter

  负责数据汇报的程序统一叫做 Exporter, 而不同的 Exporter 负责不同的业务。 它们具有统一命名格式,即 xx_exporter,例如负责主机信息收集的 node_exporter。

songjiayang.gitbooks.io/prometheus/…