Prometheus监控概述
一、监控系统概论
监控系统在这里特指对数据中心的监控,主要针对数据中心内的硬件和软件进行监控和告警。企业的 IT 架构逐步从传统的物理服务器,迁移到以虚拟机为主导的 IaaS 云。无论基础架构如何调整,都离不开监控系统的支持。
不仅如此。越来越复杂的数据中心环境对监控系统提出了更越来越高的要求:需要监控不同的对象,例如容器,分布式存储,SDN网络,分布式系统。各种应用程序等,种类繁多,还需要采集和存储大量的监控数据,例如每天数TB数据的采集汇总。以及基于这些监控数据的智能分析,告警及预警等。
在每个企业的数据中心内,或多或少都会使用一些开源或者商业的监控系统。从监控对象的角度来看,可以将监控分为网络监控,存储监控,服务器监控和应用监控等,因为需要监控数据中心的各个方面。所以监控系统需要做到面面俱到,在数据中心中充当“天眼“角色。


时间序列数据库当中(TSDB):属于同一指标名称,同一标签集合的、有时间戳标记的数据流。除了存储的时间序列,Prometheus 还可以根据查询请求产生临时的、衍生的时间序列作为返回结果。
OpenTSDB 中使用的标记法相同。
scrape configuration documentation
scrape configuration documentation
对每一个实例而言,Prometheus 按照以下时序来存储所采集的数据样本:
-
up{job=": 1 表示该实例正常工作", instance=" "} -
up{job=": 0 表示该实例故障", instance=" "} -
scrape_duration_seconds{job="表示拉取数据的时间间隔", instance=" "} -
scrape_samples_post_metric_relabeling{job="表示采用重定义标签(relabeling)操作后仍然剩余的样本数", instance=" "} -
scrape_samples_scraped{job="表示从该数据源获取的样本数", instance=" "}
其中 up 时序可以有效应用于监控该实例是否正常工作。
Graphite 功能较少,它专注于两件事,存储时序数据, 可视化数据,其他功能需要安装相关插件,而 Prometheus 属于一站式,提供告警和趋势分析的常见功能,它提供更强的数据存储和查询能力。
InfluxDB 是一个开源的时序数据库,主要用于存储数据,如果想搭建监控告警系统, 需要依赖其他系统。
OpenTSDB 是一个分布式时序数据库,它依赖 Hadoop 和 HBase,能存储更长久数据, 如果你系统已经运行了 Hadoop 和 HBase, 它是个不错的选择。
Nagios 数据不支持自定义 Labels, 不支持查询,告警也不支持去噪,分组, 没有数据存储,如果想查询历史状态,需要安装插件。
Sensu 广义上讲是 Nagios 的升级版本,它解决了很多 Nagios 的问题,如果你对 Nagios 很熟悉,使用 Sensu 是个不错的选择。
总结
- Prometheus 属于一站式监控告警平台,依赖少,功能齐全。
- Prometheus 支持对云或容器的监控,其他系统主要对主机监控。
- Prometheus 数据查询语句表现力更强大,内置更强大的统计函数。
- Prometheus 在数据存储扩展性以及持久性上没有 InfluxDB,OpenTSDB,Sensu 好。
六、Export
6.1、文本格式
在讨论 Exporter 之前,有必要先介绍一下 Prometheus 文本数据格式,因为一个 Exporter 本质上就是将收集的数据,转化为对应的文本格式,并提供 http 请求。
Exporter 收集的数据转化的文本内容以行 (\n) 为单位,空行将被忽略, 文本内容最后一行为空行
注释
文本内容,如果以 # 开头通常表示注释。
- 以
# HELP开头表示 metric 帮助说明。 - 以
# TYPE开头表示定义 metric 类型,包含counter,gauge,histogram,summary, 和untyped类型。 - 其他表示一般注释,供阅读使用,将被 Prometheus 忽略。
采样数据
内容如果不以 # 开头,表示采样数据。它通常紧挨着类型定义行,满足以下格式:
metric_name [
"{" label_name "=" `"` label_value `"` { "," label_name "=" `"` label_value `"` } [ "," ] "}"
] value [ timestamp ]
- 1.
- 2.
- 3.
下面是一个完整的例子:
# HELP http_requests_total The total number of HTTP requests.
# TYPE http_requests_total counter
http_requests_total{method="post",code="200"} 1027 1395066363000
http_requests_total{method="post",code="400"} 3 1395066363000
# Escaping in label values:
msdos_file_access_time_seconds{path="C:\\DIR\\FILE.TXT",error="Cannot find file:\n\"FILE.TXT\""} 1.458255915e9
# Minimalistic line:
metric_without_timestamp_and_labels 12.47
# A weird metric from before the epoch:
something_weird{problem="division by zero"} +Inf -3982045
# A histogram, which has a pretty complex representation in the text format:
# HELP http_request_duration_seconds A histogram of the request duration.
# TYPE http_request_duration_seconds histogram
http_request_duration_seconds_bucket{le="0.05"} 24054
http_request_duration_seconds_bucket{le="0.1"} 33444
http_request_duration_seconds_bucket{le="0.2"} 100392
http_request_duration_seconds_bucket{le="0.5"} 129389
http_request_duration_seconds_bucket{le="1"} 133988
http_request_duration_seconds_bucket{le="+Inf"} 144320
http_request_duration_seconds_sum 53423
http_request_duration_seconds_count 144320
# Finally a summary, which has a complex representation, too:
# HELP rpc_duration_seconds A summary of the RPC duration in seconds.
# TYPE rpc_duration_seconds summary
rpc_duration_seconds{quantile="0.01"} 3102
rpc_duration_seconds{quantile="0.05"} 3272
rpc_duration_seconds{quantile="0.5"} 4773
rpc_duration_seconds{quantile="0.9"} 9001
rpc_duration_seconds{quantile="0.99"} 76656
rpc_duration_seconds_sum 1.7560473e+07
rpc_duration_seconds_count 2693
- 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.
需要特别注意的是,假设采样数据 metric 叫做 x, 如果 x 是 histogram 或 summary 类型必需满足以下条件:
- 采样数据的总和应表示为
x_sum。 - 采样数据的总量应表示为
x_count。 summary类型的采样数据的 quantile 应表示为x{quantile="y"}。histogram类型的采样分区统计数据将表示为x_bucket{le="y"}。histogram类型的采样必须包含x_bucket{le="+Inf"}, 它的值等于x_count的值。summary和historam中quantile和le必需按从小到大顺序排列。
6.2、常用查询
收集到 node_exporter 的数据后,我们可以使用 PromQL 进行一些业务查询和监控,下面是一些比较常见的查询。
注意:以下查询均以单个节点作为例子,如果大家想查看所有节点,将 instance="xxx" 去掉即可。
CPU 使用率
100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
- 1.
CPU 各 mode 占比率
avg by (instance, mode) (irate(node_cpu_seconds_total[5m])) * 100
- 1.
机器平均负载
node_load1{instance="xxx"} // 1分钟负载
node_load5{instance="xxx"} // 5分钟负载
node_load15{instance="xxx"} // 15分钟负载
- 1.
- 2.
- 3.
内存使用率
100 - ((node_memory_MemFree_bytes+node_memory_Cached_bytes+node_memory_Buffers_bytes)/node_memory_MemTotal_bytes) * 100
- 1.
磁盘使用率
100 - node_filesystem_free{instance="xxx",fstype!~"rootfs|selinuxfs|autofs|rpc_pipefs|tmpfs|udev|none|devpts|sysfs|debugfs|fuse.*"} / node_filesystem_size{instance="xxx",fstype!~"rootfs|selinuxfs|autofs|rpc_pipefs|tmpfs|udev|none|devpts|sysfs|debugfs|fuse.*"} * 100
- 1.
或者你也可以直接使用 {fstype=“xxx”} 来指定想查看的磁盘信息
网络 IO
// 上行带宽
sum by (instance) (irate(node_network_receive_bytes{instance="xxx",device!~"bond.*?|lo"}[5m])/128)
// 下行带宽
sum by (instance) (irate(node_network_transmit_bytes{instance="xxx",device!~"bond.*?|lo"}[5m])/128)
- 1.
- 2.
- 3.
- 4.
- 5.
网卡出/入包
// 入包量
sum by (instance) (rate(node_network_receive_bytes{instance="xxx",device!="lo"}[5m]))
// 出包量
sum by (instance) (rate(node_network_transmit_bytes{instance="xxx",device!="lo"}[5m]))