监控系统基础
监控系统组件
监控系统功能组件
◼ 指标数据采集(抓取)
◼ 指标数据存储
◼ 指标数据趋势分析及可视化
◼ 告警
监控体系
监控体系(自底向上)
◼ 系统层监控
◆ 系统监控:CPU、Load、Memory、Swap、Disk IO、Processes、Kernel Parameters、……
◆ 网络监控:网络设备、工作负载、网络延迟、丢包率、……
◼ 中间件及基础设施类系统监控
◆ 消息中间件:Kafka、RocketMQ和RabbitMQ等;
◆ Web服务容器:Tomcat和Jetty等;
◆ 数据库及缓存系统:MySQL、PostgreSQL、MogoDB、ElasticSearch和Redis等;
◆ 数据库连接池:ShardingSpere等;
◆ 存储系统:NFS和Ceph等
◼ 应用层监控
◆ 用于衡量应用程序代码的状态和性能
◼ 业务层监控
◆ 用于衡量应用程序的价值,例如电子商务网站上的销售量
◆ QPS、DAU日活、转化率;
◆ 业务接口:登录数、注册数、订单量、搜索量和支付量等;
云原生时代的可观测性
可观测性系统
◼ 指标监控(Metrics):随时间推移产生的一些与监控相关的可聚合数据点;
◼ 日志监控(Logging):离散式的日志或事件;
◼ 链路跟踪(Tracing):分布式应用调用链跟踪;
CNCF将可观测性和数据分析归类一个单独的类别,且划分成了4个子类
◼ 监控系统:以Prometheus等为代表;
◼ 日志系统:以ElasticStack和PLG Stack等为代表;
◼ 分布式调用链跟踪系统:以Zipkin、Jaeger、SkyWalking、Pinpoint等为代表;
◼ 混沌工程系统(稳定性测试):以ChaosMonkey和ChaosBlade等为代表
著名的监控方法论
Google的四个黄金指标
◼ 常用于在服务级别帮助衡量终端用户体验、服务中断、业务影响等层面的问题
◼ 适用于应用及服务监控
Netflix的USE方法
◼ 全称为“Utilization Saturation and Errors Method”
◼ 主要用于分析系统性能问题,可以指导用户快速识别资源瓶颈以及错误的方法
◼ 应用于主机指标监控
Weave Cloud的RED方法
◼ Weave Cloud基于Google的四个黄金指标的原则下结合Prometheus以及Kubernetes容器实践,细化和总结的方法论,特别适合于云原生应用以及微服务架构应用的监控和度量
Google SRE的四黄金指标
延迟(Latency)
◼ 服务请求所需要的时长,例如HTTP请求平均延迟
◼ 应用程序响应时间会受到所有核心系统资源(包括网络、存储、CPU和内存)延迟的影响
◼ 需要区分失败请求和成功请求
流量(Traffic),有时也称为吞吐量
◼ 衡量服务的容量需求, 例如每秒处理的HTTP请求数或者数据库系统的事务数量
◼ 吞吐量指标包括每秒 Web 请求、API 调用等示例,并且被描述为通常表示为每秒请求数的需求
错误(Errors)
◼ 失败的请求(流量)的数量,通常以绝对数量或错误请求占请求总数的百分比表示
◆请求失败的速率,用于衡量错误发生的情况
◼ 例如,HTTP 500错误数等显式失败,返回错误内容或无效内容等隐式失败,以及由策略原因导致的失败(例如强制要求响应时间超过30毫秒的请求视为错误);
饱和度(Saturation)
◼ 衡量资源的使用情况,用于表达应用程序有多“满”
◆资源的整体利用率,包括 CPU(容量、配额、节流)、内存(容量、分配)、存储(容量、分配和 I/O 吞吐量)和网络
◼ 例如内存、CPU、I/O、磁盘等资源的使用量
USE方法
USE方法由Netflix的内核和性能工程师Rendan Gregg提出,主要用于分析系统性能问题
◼ 使用率(Utilization)
◆关注系统资源的使用情况。 这里的资源主要包括但不限于:CPU,内存,网络,磁盘等等
◆ 100%的使用率通常是系统性能瓶颈的标志
◼ 饱和度(Saturation)
◆例如CPU的平均运行排队长度,这里主要是针对资源的饱和度(注意,不同于4大黄金信号)
◆任何资源在某种程度上的饱和都可能导致系统性能的下降
◼ 错误(Errors)
◆ 错误计数
◆ 例如:“网卡在数据包传输过程中检测到的以太网网络冲突了14次”
RED方法
RED方法是Weave Cloud在基于Google的4个黄金指标的原则下结合Prometheus以及Kubernetes容器实践,细化和总结的方法论,特别适合于云原生应用以及微服务架构应用的监控和度量
在四大黄金指标的原则下,RED方法可以有效地帮助用户衡量云原生以及微服务应用下的用户体验问题;
RED方法主要关注以下3种关键指标
◼ (Request)Rate:每秒钟接收的请求数;
◼ (Request)Errors:每秒失败的请求数;
◼ (Request)Duration:每个请求所花费的时长;
Prometheus
What is Prometheus Monitoring?
首先,Prometheus是一款时序(time series)数据库;但它的功能却并非止步于TSDB,而是一款设计用于进行目标(Target)监控的关键组件;
结合生态系统内的其它组件,例如Pushgateway、Altermanager和Grafana等,可构成一个完整的IT监控系统;
时序数据简介
时序数据,是在一段时间内通过重复测量(measurement)而获得的观测值的集合;将这些观测值绘制于图形之上,它会有一个数据轴和一个时间轴;
◼ As our world gets increasingly instrumented, sensors and systems are constantly emitting a relentless stream of time series data.
◼ Weather records, economic indicators and patient health evolution metrics — all are time series data.
服务器指标数据、应用程序性能监控数据、网络数据等也都是时序数据;
What does Prometheus do?
基于HTTP call,从配置文件中指定的网络端点(endpoint)上周期性获取指标数据
How does Prometheus work?
Prometheus支持通过三种类型的途径从目标上“抓取(Scrape)”指标数据;
◼ Exporters
◼ Instrumentation
◼ Pushgateway
Prometheus刮擦指标数据的三个途径;
◼ By ‘instrumenting’ your application, meaning that your application will expose Prometheus compatible metrics on agiven URL.
◼ By using of the prebuilt exporters : Prometheus has an entire collection of exporters for existing technologies.
◆ You can for example find prebuilt exporters for Linux machine monitoring (node exporter), for very established databases (SQL exporter or MongoDB exporter) and even for HTTP load balancers (such as the HAProxy exporter).
◼ By using the Pushgateway : sometimes you have applications or jobs that do not expose metrics directly.
◆ Those applications are either not designed for it (such as batch jobs for example), or you may have made the choice not to expose those metrics directly via your app.
Pull and Push
Prometheus同其它TSDB相比有一个非常典型的特性:它主动从各Target上“拉取(pull)”数据,而非等待被监控端的“推送(push)”;
两个方式各有优劣,其中,Pull模型的优势在于:
◼ 集中控制:有利于将配置集在Prometheus Server上完成,包括指标及采取速率等;
◼ Prometheus的根本目标在于收集在Target上预先完成聚合的聚合型数据,而非一款由事件驱动的存储系统;
Prometheus的生态组件
Prometheus负责时序型指标数据的采集及存储,但数据的分析、聚合及直观展示以及告警等功能并非由Prometheus Server所负责;
Prometheus 生态圈中包含了多个组件,其中部分组件可选
◼ Prometheus Server: 收集和存储时间序列数据;
◼ Client Library: 客户端库,目的在于为那些期望原生提供Instrumentation功能的应用程序提供便捷的开发途径;
◼ Push Gateway: 接收那些通常由短期作业生成的指标数据的网关,并支持由Prometheus Server进行指标拉取操作;
◼ Exporters: 用于暴露现有应用程序或服务(不支持Instrumentation)的指标给Prometheus Server;
◼ Alertmanager: 从Prometheus Server接收到“告警通知”后,通过去重、分组、路由等预处理功能后以高效向用户完成告警信息发送;
◼ Data Visualization:Prometheus Web UI (Prometheus Server内建),及Grafana等;
◼ Service Discovery:动态发现待监控的Target,从而完成监控配置的重要组件,在容器化环境中尤为有用;该组件目前由Prometheus Server内建支持;
Prometheus数据模型
Prometheus仅用于以“键值”形式存储时序式的聚合数据,它并不支持存储文本信息;
◼ 其中的“键”称为指标(Metric),它通常意味着CPU速率、内存使用率或分区空闲比例等;
◼ 同一指标可能会适配到多个目标或设备,因而它使用“标签”作为元数据,从而为Metric添加更多的信息描述纬度;
◼ 这些标签还可以作为过滤器进行指标过滤及聚合运算;
指标类型(Metric Types)
Prometheus使用4种方法来描述监视的指标
◼ Counter:计数器,用于保存单调递增型的数据,例如站点访问次数等;不能为负值,也不支持减少,但可以重置回0;
◼ Gauge:仪表盘,用于存储有着起伏特征的指标数据,例如内存空闲大小等;
◆Gauge是Counter的超集;但存在指标数据丢失的可能性时,Counter能让用户确切了解指标随时间的变化状态,而Gauge则可能随时间流逝而精准度越来越低;
◼ Histogram:直方图,它会在一段时间范围内对数据进行采样,并将其计入可配置的bucket之中;Histogram能够存储更多的信息,包括样本值分布在每个bucket(bucket自身的可配置)中的数量、所有样本值之和以及总的样本数量,从而Prometheus能够使用内置的函数进行如下操作:
◆ 计算样本平均值:以值的总和除以值的数量;
◆ 计算样本分位值:分位数有助于了解符合特定标准的数据个数;例如评估响应时长超过1秒钟的请求比例,若超过20%即发送告警等;
◼ Summary:摘要,Histogram的扩展类型,但它是直接由被监测端自行聚合计算出分位数,并将计算结果响应给Prometheus Server的样本采集请求;因而,其分位数计算是由由监控端完成;
作业(Job)和实例(Instance)
Instance:能够接收Prometheus Server数据Scrape操作的每个网络端点(endpoint),即为一个Instance(实例);
通常,具有类似功能的Instance的集合称为一个Job,例如一个MySQL主从复制集群中的所有MySQL进程;
PromQL
Prometheus提供了内置的数据查询语言PromQL(全称为Prometheus Query Language),支持用户进行实时的数据查询及聚合操作;
PromQL支持处理两种向量,并内置提供了一组用于数据处理的函数
◼ 即时向量:最近一次的时间戳上跟踪的数据指标;
◼ 时间范围向量:指定时间范围内的所有时间戳上的数据指标;
Instrumentation(程序仪表)
任何能够支持Scrape指标数据的应用程序都首先要具有一个测量系统;
在Prometheus的语境中,Instrumentation是指附加到应用程序中的那些用于暴露程序指标数据的客户端库;
◼ 程序员借助于这些客户端库编写代码生成可暴露的指标数据;
Exporters
对于那些未内建Instrumentation,且也不便于自行添加该类组件以暴露指标数据的应用程序来说,常用的办法是于待监控的目标应用程序外部运行一个独立指标暴露程序,该类型的程序即统称为Exporter;
换句话说,Exporter负责从目标应用程序上采集和聚合原始格式的数据,并转换或聚合为Prometheus格式的指标向外暴露;
Prometheus站点上提供了大量的Exporter
Alerts
抓取到异常值后,Prometheus支持通过“告警(Alert)”机制向用户发送反馈或警示,以触发用户能够及时采取应对措施;
Prometheus Server仅负责生成告警指示,具体的告警行为由另一个独立的应用程序AlertManager负责;
◼ 告警指示由Prometheus Server基于用户提供的“告警规则”周期性计算生成;
◼ Alertmanager接收到Prometheus Server发来的告警指示后,基于用户定义的告警路由(route)向告警接收人(receivers)发送告警信息;
Prometheus架构及组件
Prometheus Architecture
Prometheus的关键组件
关键组件
◼ Prometheus-Server:Prometheus监控系统的核心组件
◼ Exporters:指标暴露器
◆ node-exporter
◆ mysql-exporter
◆……
◼ AlertManager
◼ PushGateway
工作模式
◼ Prometheus Server基于服务发现(Service Discovery)机制或静态配置获取要监视的目标(Target),并通过每个目标上的指标exporter来采集(Scrape)指标数据
◼ Prometheus Server内置了一个基于文件的时间序列存储来持久存储指标数据,用户可使用PromDash或PromQL接口来检索数据,也能够按需将告警需求发往Alertmanager完成告警内容发送
◼ 一些短期运行的作业的生命周期过短,难以有效地将必要的指标数据供给到Server端,它们一般会采用推送(Push)方式输出指标数据,Prometheus借助于Pushgateway接收这些推送的数据,进而由Server端进行抓取
Prometheus的特性
关键特性
◼ 多维护数据模型:以指标名称及附加的label标识时间序列
◼ 特有的数据查询语言:PromQL
◼ 单个服务器节点即可正常工作,不依赖分布式存储
◼ 基于HTTP协议,以Pull模式完成指标数据采集
◼ 借助于PushGateway,支持Push模式的指标数据采集
◼ 使用服务发现机制动态发现Target,或静态配置要监控的Target
◼ 支持多种Graph和Dashboard
不适用的场景
◼ Prometheus是一款指标监控系统,不适合存储事件及日志;
◼ Prometheus认为只有最近的监控数据才有查询的需要,其本地存储的设计初衷只是保存短期数据,因而不支持针对大量的历史数据进行存储;
◆ 若需要存储长期的历史数据,建议基于远端存储机制将数据保存于InfluxDB或OpenTSDB等系统中;
◼ Prometheus的集群机制成熟度不高,即便基于Thanos亦是如此;
部署Prometheus
参考文章Prometheus部署及应用
Exporters
客户端库
应用程序自己并不会直接生成指标数据,这依赖于开发人员将相关的客户端库添加至应用程序中构建出的测量系统(instrumentation system)来完成。
◼ Prometheus为包括Go、Python、Java(或Scala)和Ruby等主流的编程语言提供了各自适用的客户端库,另外还有适用于Bash、C、C++、C#、Node.js、Haskell、Erlang、Perl、PHP和Rust等多种编程语言的第三方库可用;
◼ 通常,三两行代码即能将客户端库整合进应用程序中实现直接测量(direct instrumentation)机制;
客户端库主要负责处理所有的细节类问题,例如线程安全和记账,以及生成文本格式的指标以数据响应HTTP请求等;
客户端库通常还会额外提供一些指标,例如CPU使用率和垃圾回收统计信息等,具体的实现则取决于库和相关的运行时环境;
Exporter基础
对于那些非由用户可直接控制的应用代码来说,为其添加客户端库以进行直接测量很难实现
◼ 操作系统内核就是一个典型的示例,它显然不大可能易于实现添加自定义代码通过HTTP协议输出Prometheus格式的指标
◼ 但这一类的程序一般都会通常某种接口输出其内在的指标,只不过这些指标可能有着特殊的格式,例如Linux内核的特有指标格式,或者SNMP指标格式等
◼ 这些指标需要对它进行适当的解析和处理以转换为合用的目标格式,Exporter(指标暴露器)是完成此类转换功能的应用程序
Exporter独立运行于要获取其测量指标的应用程序之外,负责接收来自于Prometheus Server的指标获取请求,它通过目标应用程序(真正的目标)内置的指标接口获取指标数据,并将这些指标数据转换为合用的目标格式后响应给Prometheus
◼ Exporter更像是“一对一”的代理,它作为Prometheus Server的target存在,工作于应用程序的指标接口和Prometheus的文本指标格式之间转换数据格式
◼ 但Exporter不存储也不缓存任何数据
部署Node Export监控系统级指标
参考文章Prometheus部署及应用
Node Exporter的指标
启用或禁用Node Exporter内生支持的指标
◼ Collectors are enabled by providing a –collector.<name> flag.
◼ Collectors that are enabled by default can be disabled by providing a –no-collector.<name> flag.
常用指标
◼ node_cpu_seconds_total
◼ node_memory_MemTotal_bytes
◼ node_filesystem_size_bytes{mount_point=PATH}
◼ node_system_unit_state{name=}
◼ node_vmstat_pswpin:系统每秒从磁盘读到内存的字节数;
◼ node_vmstat_pswpout:系统每秒钟从内存写到磁盘的字节数;
相关文档
◼ https://github.com/prometheus/node_exporter
适用于主机监控的USE方法
USE是使用率(Utilization)、饱和度(Saturation)和错误(Error)的缩写,由Netflix的内核和性能工程师Brendan Gregg开发;
◼ USE方法可以概括为:针对每个资源,检查使用率、饱和度和错误;
◆ 资源:系统的一个组件,在USE中,它指的是一个传统意义上的物理服务器组件,如CPU、内存和磁盘等;
◆ 使用率:资源忙于工作的平均时间,它通常用随时间变化的百分比进行表示;
◆ 饱和度:资源排队工作的指标,无法再处理额外的工作;通常用队列长度表示;
◆ 错误:资源错误事件的计数;
◼ 对CPU来说,USE通常意味着如下概念
◆ CPU使用率随时间的百分比;
◆ CPU饱和度,等待CPU的进程数;
◆ 错误,通常对CPU不太有影响;
◼ 对内存来说,USE的意义相似
◆ 内存使用率随时间的百分比;
◆ 内存饱和度,可通过监控swap进行测量;
◆ 错误,通常不太关键;
CPU使用率
每台主机CPU在5分钟内的平均使用率
CPU的饱和度
跟踪CPU的平均负载就能获取到相关主机的CPU饱和度,实际上,它是将主机上的CPU数量考虑在内的一段时间内的平均运行队列长度
◼ 平均负载少于CPU的数量是正常状况,而长时间内超过CPU数量则表示CPU已然饱和;
◼ node_load1 > on (instance) 2 * count (node_cpu_seconds_total{mode=”idle”}) by (instance)
◆ 查询1分钟平均负载超过主机CPU数量两瓿的时间序列
内存使用率
node_exporter暴露了多个以node_memory为前缀的指标,我们重点关注如下几个
◼ node_memory_MemTotal_bytes
◼ node_memory_MemFree_bytes
◼ node_memory_Buffers_bytes
◼ node_memory_Cached_bytes
计算使用率
◼ 可用空间:上面后三个指标之和;
◼ 已用空间:总空间减去可用空间;
◼ 使用率:已用空间除以总空间;
PromQL
Prometheus时间序列
时间序列数据:按照时间顺序记录系统、设备状态变化的数据,每个数据称为一个样本;
◼ 数据采集以特定的时间周期进行,因而,随着时间流逝,将这些样本数据记录下来,将生成一个离散的样本数据序列;
◼ 该序列也称为向量(Vector);而将多个序列放在同一个坐标系内(以时间为横轴,以序列为纵轴),将形成一个由数据点组成的矩阵;
PromQL简介
Prometheus基于指标名称(metrics name)以及附属的标签集(labelset)唯一定义一条时间序列
◼ 指标名称代表着监控目标上某类可测量属性的基本特征标识
◼ 标签则是这个基本特征上再次细分的多个可测量维度
基于PromQL表达式,用户可以针对指定的特征及其细分的纬度进行过滤、聚合、统计等运算从而产生期望的计算结果
PromQL (Prometheus Query Language)是Prometheus Server内置数据查询语言
◼ PromQL使用表达式(expression)来表述查询需求
◼ 根据其使用的指标和标签,以及时间范围,表达式的查询请求可灵活地覆盖在一个或多个时间序列的一定范围内的样本之上,甚至是只包含单个时间序列的单个样本
Prometheus数据模型
Prometheus中,每个时间序列都由指标名称(Metric Name)和标签(Label)来唯一标识,格式为“<metric name>{<label name>=<label value>, …}”;
◼ 指标名称:通常用于描述系统上要测定的某个特征;
◆ 例如,http_requests_total表示接收到的HTTP请求总数;
◆ 支持使用字母、数字、下划线和冒号,且必须能匹配RE2规范的正则表达式;
◼ 标签:键值型数据,附加在指标名称之上,从而让指标能够支持多纬度特征;可选项;
◆ 例如,http_requests_total{method=GET}和http_requests_total{method=POST}代表着两个不同的时间序列;
◆ 标签名称可使用字母、数字和下划线,且必须能匹配RE2规范的正则表达式;
◆ 以“_ _”为前缀的名称为Prometheus系统预留使用;
Metric Name的表示方式有两种
◼ 后一种通常用于Prometheus内部
样本数据格式
Prometheus的每个数据样本由两部分组成
◼ float64格式的数据
◼ 毫秒精度的时间戳
指标名称及标签使用注意事项
指标名称和标签的特定组合代表着一个时间序列;
◼ 指标名称相同,但标签不同的组合分别代表着不同的时间序列;
◼ 不同的指标名称自然更是代表着不同的时间序列;
PromQL支持基于定义的指标维度进行过滤和聚合
◼ 更改任何标签值,包括添加或删除标签,都会创建一个新的时间序列
◼ 应该尽可能地保持标签的稳定性,否则,则很可能创建新的时间序列,更甚者会生成一个动态的数据环境,并使得监控的数据源难以跟踪,从而导致建立在该指标之上的图形、告警及记录规则变得无效
PromQL的数据类型
PromQL的表达式中支持4种数据类型
◼ 即时向量(Instant Vector):特定或全部的时间序列集合上,具有相同时间戳的一组样本值称为即时向量;
◼ 范围向量(Range Vector):特定或全部的时间序列集合上,在指定的同一时间范围内的所有样本值;
◼ 标量(Scalar):一个浮点型的数据值;
◼ 字符串(String):支持使用单引号、双引号或反引号进行引用,但反引号中不会对转义字符进行转义;
时间序列选择器(Time series Selectors)
PromQL的查询操需要针对有限个时间序列上的样本数据进行,挑选出目标时间序列是构建表达式时最为关键的一步
◼ 用户可使用向量选择器表达式来挑选出给定指标名称下的所有时间序列或部分时间序列的即时(当前)样本值或至过去某个时间范围内的样本值,前者称为即时向量选择器,后者称为范围向量选择器
◆ 即时向量选择器(Instant Vector Selectors):返回0个、1个或多个时间序列上在给定时间戳(instant)上的各自的一个样本,该样本也可称为即时样本;
◆ 范围向量选择器(Range Vector Selectors) :返回0个、1个或多个时间序列上在给定时间范围内的各自的一组样本;
向量表达式使用要点
表达式的返回值类型亦是即时向量、范围向量、标题或字符串4种数据类型其中之一,但是,有些使用场景要求表达式返回值必须满足特定的条件,例如
◼ 需要将返回值绘制成图形时,仅支持即时向量类型的数据;
◼ 对于诸如rate一类的速率函数来说,其要求使用的却又必须是范围向量型的数据;
由于范围向量选择器的返回的是范围向量型数据,它不能用于表达式浏览器中图形绘制功能,否则,表达式浏览器会返回“Error executing query: invalid expression type “range vector” for range query, must be Scalar or instant Vector”一类的错误
◼ 事实上,范围向量选择几乎总是结合速率类的函数rate一同使用
即时向量选择器
即时向量选择器由两部分组成;
◼ 指标名称:用于限定特定指标下的时间序列,即负责过滤指标;可选;
◼ 匹配器(Matcher):或称为标签选择器,用于过滤时间序列上的标签;定义在{}之中;可选;
显然,定义即时向量选择器时,以上两个部分应该至少给出一个;于是,这将存在以下三种组合;
◼ 仅给定指标名称,或在标签名称上使用了空值的匹配器:返回给定的指标下的所有时间序列各自的即时样本;
◆例如,http_requests_total和http_requests_total{}的功能相同,都是用于返回http_requests_total指标下各时间序列的即时样本;
◼ 仅给定匹配器:返回所有符合给定的匹配器的所有时间序列上的即时样本;
◆ 注意:这些时间序列可能会有着不同的指标名称;
◆ 例如, {job=”.*”, method=”get”}
◼ 指标名称和匹配器的组合:返回给定的指定下的,且符合给定的标签过滤器的所有时间序列上的即时样本;
◆ 例如, http_requests_total{method=”get”}
匹配器(Matcher)
匹配器用于定义标签过滤条件,目前支持如下4种匹配操作符;
◼ =: Select labels that are exactly equal to the provided string.
◼ !=: Select labels that are not equal to the provided string.
◼ =~: Select labels that regex-match the provided string.
◼ !~: Select labels that do not regex-match the provided string.
注意事项
◼ 匹配到空标签值的匹配器时,所有未定义该标签的时间序列同样符合条件;
◆ 例如,http_requests_total{env= “”},则该指标名称上所有未使用该标签(env)的时间序列也符合条件,比如时间序列http_requests_total{method =”get”} ;
◼ 正则表达式将执行完全锚定机制,它需要匹配指定的标签的整个值;
◼ 向量选择器至少要包含一个指标名称,或者至少有一个不会匹配到空字符串的匹配器;
◆ 例如,{job=””}为非法的选择器;
◼ 使用“__name__”做为标签名称,还能够对指标名称进行过滤;
◆ 例如,{__name__=~”http_requests_.*”}能够匹配所有以“ http_requests_ ”为前缀的所有指标;
范围向量选择器
同即时向量选择器的唯一不同之处在于,范围向量选择器需要在表达式后紧跟一个方括号[ ]来表达需在时间时序上返回的样本所处的时间范围;
◼ 时间范围:以当前时间为基准时间点,指向过去一个特定的时间长度;例如[5m]便是指过去5分钟之内;
时间格式:一个整数后紧跟一个时间单位,例如“5m”中的“m”即是时间单位;
◼ 可用的时间单位有ms(毫秒)、s(秒)、m(分钟)、h(小时)、d(天)、w(周)和y(年);
◼ 必须使用整数时间,且能够将多个不同级别的单位进行串联组合,以时间单位由大到小为顺序,例如1h30m,但不能使用1.5h;
需要注意的是,范围向量选择器返回的是一定时间范围内的数据样本,虽然不同时间序列的数据抓取时间点相同,但它们的时间戳并不会严格对齐;
◼ 多个Target上的数据抓取需要分散在抓取时间点前后一定的时间范围内,以均衡Prometheus Server的负载;
◼ 因而,Prometheus在趋势上准确,但并非绝对精准;
偏移量修改器
默认情况下,即时向量选择器和范围向量选择器都以当前时间为基准时间点,而偏移量修改器能够修改该基准;
偏移量修改器的使用方法是紧跟在选择器表达式之后使用“offset”关键字指定
◼ “http_requests_total offset 5m”,表示获取以http_requests_total为指标名称的所有时间序列在过去5分钟之时的即时样本;
◼ “http_requests_total[5m] offset 1d”,表示获取距此刻1天时间之前的5分钟之内的所有样本;
PromQL的指标类型
PromQL有四个指标类型,它们主要由Prometheus的客户端库使用
◼ Counter:计数器,单调递增,除非重置(例如服务器或进程重启);
◼ Gauge:仪表盘,可增可减的数据;
◼ Histogram:直方图,将时间范围内的数据划分成不同的时间段,并各自评估其样本个数及样本值之和,因而可计算出分位数;
◆ 可用于分析因异常值而引起的平均值过大的问题;
◆ 分位数计算要使用专用的histogram_quantile函数;
◼ Summary:类似于Histogram,但客户端会直接计算并上报分位数;
Prometheus Server并不使用类型信息,而是将所有数据展平为时间序列
Counter和Gauge
通常,Counter的总数并没有直接作用,而是需要借助于rate、topk、increase和irate等函数来生成样本数据的变化状况(增长率);
◼ rate(http_requests_total[2h]),获取2小内,该指标下各时间序列上的http总请求数的增长速率;
◼ topk(3, http_requests_total),获取该指标下http请求总数排名前3的时间序列;
◼ irate(http_requests_total[2h]),高灵敏度函数,用于计算指标的瞬时速率;
◆ 基于样本范围内的最后两个样本进行计算,相较于rate函数来说,irate更适用于短期时间范围内的变化速率分析;
Gauge用于存储其值可增可减的指标的样本数据,常用于进行求和、取平均值、最小值、最大值等聚合计算;也会经常结合PromQL的predict_linear和delta函数使用;
◼ predict_linear(v range-vector, t, scalar)函数可以预测时间序列v在t秒后的值,它通过线性回归的方式来预测样本数据的Gauge变化趋势;
◼ delta(v range-vector)函数计算范围向量中每个时间序列元素的第一个值与最后一个值之差,从而展示不同时间点上的样本值的差值;
◆ delta(cpu_temp_celsius{host=”web01.magedu.com”}[2h]),返回该服务器上的CPU温度与2小时之前的差异;
Histogram
Histogram是一种对数据分布情况的图形表示,由一系列高度不等的长条图(bar)或线段表示,用于展示单个测度的值的分布
◼ 它一般用横轴表示某个指标维度的数据取值区间,用纵轴表示样本统计的频率或频数,从而能够以二维图的形式展现数值的分布状况
◼ 为了构建Histogram,首先需要将值的范围进行分段,即将所有值的整个可用范围分成一系列连续、相邻(相邻处可以是等同值)但不重叠的间隔,而后统计每个间隔中有多少值
◼ 从统计学的角度看,分位数不能被聚合,也不能进行算术运算;
对于Prometheus来说,Histogram会在一段时间范围内对数据进行采样(通常是请求持续时长或响应大小等),并将其计入可配置的bucket(存储桶)中
◼ Histogram事先将特定测度可能的取值范围分隔为多个样本空间,并通过对落入bucket内的观测值进行计数以及求和操作
◼ 与常规方式略有不同的是,Prometheus取值间隔的划分采用的是累积(Cumulative)区间间隔机制,即每个bucket中的样本均包含了其前面所有bucket中的样本,因而也称为累积直方图
◆ 可降低Histogram的维护成本
◆ 支持粗略计算样本值的分位数
◆ 单独提供了_sum和_count指标,从而支持计算平均值
Histogram类型的每个指标有一个基础指标名称<basename>,它会提供多个时间序列:
◼ <basename>_bucket{le=”<upper inclusive bound>”}:观测桶的上边界(upper inclusive bound),即样本统计区间,最大区间(包含所有样本)的名称为<basename>_bucket{le=”+Inf”};
◼ <basename>_sum:所有样本观测值的总和;
◼ <basename>_count :总的观测次数,它自身本质上是一个Counter类型的指标;
累积间隔机制生成的样本数据需要额外使用内置的histogram_quantile()函数即可根据Histogram指标来计算相应的分位数(quantile),即某个bucket的样本数在所有样本数中占据的比例
◼ histogram_quantile()函数在计算分位数时会假定每个区间内的样本满足线性分布状态,因而它的结果仅是一个预估值,并不完全准确;
◼ 预估的准确度取决于bucket区间划分的粒度;粒度越大,准确度越低;
Summary
指标类型是客户端库的特性,而Histogram在客户端仅是简单的桶划分和分桶计数,分位数计算由Prometheus Server基于样本数据进行估算,因而其结果未必准确,甚至不合理的bucket划分会导致较大的误差;
Summary是一种类似于Histogram的指标类型,但它在客户端于一段时间内(默认为10分钟)的每个采样点进行统计,计算并存储了分位数数值,Server端直接抓取相应值即可;
但Summary不支持sum或avg一类的聚合运算,而且其分位数由客户端计算并生成,Server端无法获取客户端未定义的分位数,而Histogram可通过PromQL任意定义,有着较好的灵活性;
对于每个指标,Summary以指标名称<basename>为前缀,生成如下几个个指标序列
◼ <basename>{quantile=”<φ>”},其中φ是分位点,其取值范围是(0 ≤φ≤ 1);计数器类型指标;如下是几种典型的常用分位点;
◆ 0、0.25、0.5、0.75和1几个分位点;
◆ 0.5、0.9和0.99几个分位点;
◆ 0.01、0.05、0.5、0.9和0.99几个分位点;
◼ <basename>_sum,抓取到的所有样本值之和;
◼ <basename>_count,抓取到的所有样本总数;
Prometheus的聚合函数
一般说来,单个指标的价值不大,监控场景中往往需要联合并可视化一组指标,这种联合机制即是指“聚合”操作,例如,将计数、求和、平均值、分位数、标准差及方差等统计函数应用于时间序列的样本之上生成具有统计学意义的结果等;
对查询结果事先按照某种分类机制进行分组(groupby)并将查询结果按组进行聚合计算也是较为常见的需求,例如分组统计、分组求平均值、分组求和等;
聚合操作由聚合函数针对一组值进行计算并返回单个值或少量几值作为结果
◼ Prometheus内置提供的11个聚合函数也称为聚合运算符
◼ 这些运算符仅支持应用于单个即时向量的元素,其返回值也是具有少量元素的新向量或标量
◼ 这些聚合运行符既可以基于向量表达式返回结果中的时间序列的所有标签维度进行分组聚合,也可以仅基于指定的标签维度分组后再进行分组聚合
聚合表达式
PromQL中的聚合操作语法格式可采用如下面两种格式之一
◼ <aggr-op>([parameter,] <vector expression>) [without|by (<label list>)]
◼ <aggr-op> [without|by (<label list>)] ([parameter,] <vector expression>)
分组聚合:先分组、后聚合
◼ without:从结果向量中删除由without子句指定的标签,未指定的那部分标签则用作分组标准;
◼ by:功能与without刚好相反,它仅使用by子句中指定的标签进行聚合,结果向量中出现但未被by子句指定的标签则会被忽略;
◆为了保留上下文信息,使用by子句时需要显式指定其结果中原本出现的job、instance等一类的标签
事实上,各函数工作机制的不同之处也仅在于计算操作本身,PromQL对于它们的执行逻辑相似;
11个聚合函数
sum( ):对样本值求和;
avg ( ) :对样本值求平均值,这是进行指标数据分析的标准方法;
count ( ) :对分组内的时间序列进行数量统计;
stddev ( ) :对样本值求标准差,以帮助用户了解数据的波动大小(或称之为波动程度);
stdvar ( ) :对样本值求方差,它是求取标准差过程中的中间状态;
min ( ) :求取样本值中的最小者;
max ( ) :求取样本值中的最大者;
topk ( ) :逆序返回分组内的样本值最大的前k个时间序列及其值;
bottomk ( ) :顺序返回分组内的样本值最小的前k个时间序列及其值;
quantile ( ) :分位数用于评估数据的分布状态,该函数会返回分组内指定的分位数的值,即数值落在小于
等于指定的分位区间的比例;
count_values ( ) :对分组内的时间序列的样本值进行数量统计;
二元运算符(Binary Operators)
PromQL支持基本的算术运算和逻辑运算,这类运算支持使用操作符连接两个操作数,因而也称为二元运算符或二元操作符;
◼ 支持的运算
◆ 两个标量间运算;
◆ 即时向量和标量间的运算:将运算符应用于向量上的每个样本;
◆两个即时向量间的运算:遵循向量匹配机制;
◼ 将运算符用于两个即时向量间的运算时,可基于向量匹配模式(Vector Matching)定义其运算机制;
算术运算
◼ 支持的运算符:+(加)、-(减)、*(乘)、/(除)、%(取模)和^(幂运算);
比较运算
◼ 支持的运算符:==(等值比较)、!=(不等)、>、<、>=和<=(小于等于);
逻辑/集合运算
◼ 支持的运算符:and(并且)、or(或者)和unless(除了);
◼ 目前,该运算仅允许在两个即时向量间进行,尚不支持标量参与运算;
二元运算符优先级
Prometheus的复杂运算中,二元运算符存在如下给定次序中所示的由高到低的优先级
◼ ^
◼ *, /, %
◼ +, –
◼ ==, !=, <=, <, >=, >
◼ and, unless
◼ or
具有相同优先级的运算符满足结合律(左结合),但幂运算除外,因为它是右结合机制;
可以使用括号( )改变运算次序;
向量匹配
即时向量间的运算是PromQL的特色之一;运算时,PromQL为会左侧向量中的每个元素找到匹配的元素,其匹配行为有两种基本类型
◼ 一对一 (One-to-One)
◼ 一对多或多对一 (Many-to-One, One-to-Many)
向量一对一匹配
即时向量的一对一匹配
◼ 从运算符的两边表达式所获取的即时向量间依次比较,并找到唯一匹配(标签完全一致)的样本值;
◼ 找不到匹配项的值则不会出现在结果中;
匹配表达式语法
◼ <vector expr> <bin-op> ignoring(<label list>) <vector expr>
◼ <vector expr> <bin-op> on(<label list>) <vector expr>
◆ ignore:定义匹配检测时要忽略的标签;
◆ on:定义匹配检测时只使用的标签;
◼ 例如,rate(http_requests_total{status_code=~”5.*”}[5m]) > .1 * rate(http_requests_total[5m])
◆ 左侧会生成一个即时向量,它计算出5xx响应码的各类请求的增长速率;
⚫ 除了status_code标签外,该指标通常还有其它标签;于是,status_code的值为500的标签同其它标签的每个组合将代表一个时间序列,其相应的即时样本即为结果向量的一个元素;
◆ 右侧会生成一个即时向量,它计算出所有标签组合所代表的各类请求的增长速率;
◆ 计算时,PromQL会在操作符左右两侧的结果元素中找到标签完全一致的元素进行比较;
◆ 其意义为,计算出每类请求中的500响应码在该类请求中所占的比例;
向量一对多/多对一匹配
一对多/多对一匹配
◼ “一”侧的每个元素,可与“多”侧的多个元素进行匹配;
◼ 必须使用group_left或group_right明确指定哪侧为“多”侧;
匹配表达式语法
◼ <vector expr> <bin-op> ignoring(<label list>) group_left(<label list>) <vector expr>
◼ <vector expr> <bin-op> ignoring(<label list>) group_right(<label list>) <vector expr>
◼ <vector expr> <bin-op> on(<label list>) group_left(<label list>) <vector expr>
◼ <vector expr> <bin-op> on(<label list>) group_right(<label list>) <vector expr>
Service Discovery
Prometheus为何要进行服务发现?
Prometheus Server的数据抓取工作于Pull模型,因而,它必需要事先知道各Target的位置,然后才能从相应的Exporter或Instrumentation中抓取数据
◼ 对于小型的系统环境来说,通过static_configs指定各Target便能解决问题,这也是最简单的配置方法;
◆ 每个Targets用一个网络端点(ip:port)进行标识;
◼ 对于中大型的系统环境或具有较强动态性的云计算环境来说,静态配置显然难以适用;
◼ 因此,Prometheus为此专门设计了一组服务发现机制,以便于能够基于服务注册中心(服务总线)自动发现、检测、分类可被监控的各Target,以及更新发生了变动的Target;
指标抓取的生命周期
下图展示了Prometheus上进行指标抓取的简单生命周期
◼ 在每个scrape_interval期间,Prometheus都会检查执行的作业(Job);
◼ 这些作业首先会根据Job上指定的发现配置生成target列表,此即服务发现过程;
◆ 服务发现会返回一个Target列表,其中包含一组称为元数据的标签,这些标签都以“__meta_”为前缀;
◆ 服务发现还会根据目标配置来设置其它标签,这些标签带有“__”前缀和后缀,包括“__scheme__”、“__address__”和“__metrics_path__”,分别保存有target支持使用协议(http或https,默认为http)、target的地址及指标的URI路径(默认为/metrics);
◆ 若URI路径中存在任何参数,则它们的前缀会设置为“__param_”
◆ 这些目标列表和标签会返回给Prometheus,其中的一些标签也可以配置中被覆盖;
◼ 配置标签会在抓取的生命周期中被重复利用以生成其他标签,例如,指标上的instance标签的默认值就来自于__address__标签的值;
指标抓取的生命周期
对于发现的各目标,Prometheus提供了可以重新标记(relabel) 目标的机会
◼ 它定义在job配置段的relabel_config配置中,常用于实现如下功能
◆ 将来自服务发现的元数据标签中的信息附加到指标的标签上;
◆ 过滤目标;
这之后,便是数据抓取、以及指标返回的过程;
抓取而来的指标在保存之前,还允许用户对指标重新打标并过滤的方式;
◼ 它定义在job配置段的metric_relabel_configs配置中,常用于实现如下功能
◆ 删除不必要的指标;
◆ 从指标中删除敏感或不需要的标签;
◆ 添加、编辑或修改指标的标签值或标签格式;
Prometheus可集成的服务发现机制
不同场景中,服务注册中心的指代也会有所不同
◼ 公有或私有IaaS云自身保存有平台上的所有资源信息,其API Server便可作为Prometheus的服务发现媒介;
◆ azure、ec2、digitalocean、gce、hetzner、
◼ Prometheus也可以集成到多种不同的开源服务发现工具上,以动态发现需要监控的目标;
◆Consul、Eureka Zookeeper Serverset或Airbnb Nerve等
◼ Prometheus也可以很好地集成到Kubernetes平台上,通过其API Server动态发现各类被监控的Pod(容器集)、Service、Endpoint、Ingress和Node对象;
◆它也支持基于dockerswarm和marathon两款编排工具进行服务发现;
◼ Prometheus还支持基于DNS或文件的动态发现机制;
基于文件的服务发现
基于文件的服务发现是仅仅略优于静态配置的服务发现方式,它不依赖于任何平台或第三方服务,因而也是最为简单和通用的实现方式;
◼ Prometheus Server定期从文件中加载Target信息
◆ 文件可使用JSON和YAML格式,它含有定义的Target列表,以及可选的标签信息;
◆ 下面第一个配置,能够将prometheus默认的静态配置转换为基于文件的服务发现时所需的配置;
- targets:
- localhost:9090
labels:
app: prometheus
job: prometheus
- targets:
- localhost:9100
labels:
app: node-exporter
job: node
◼ 这些文件可由另一个系统生成,例如Puppet、Ansible或Saltstack等配置管理系统,也可能是由脚本基于CMDB定期查询生成;
发现target的配置,定义在配置文件的job之中
[root@ubuntu2004 02-prometheus-sd-consul-example]#cat ../01-prometheus-basics-example/prometheus/prometheus.yml
# my global config
# Author: MageEdu <mage@magedu.com>
# Repo: http://gitlab.magedu.com/MageEdu/prometheus-configs/
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
# The job name is added as a label job=<job_name>
to any timeseries scraped from this config.
- job_name: 'prometheus'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets:
- localhost:9090
# All nodes
- job_name: 'nodes'
file_sd_configs:
- files:
- targets/nodes-*.yaml
refresh_interval: 2m
基于DNS的服务发现
基于DNS的服务发现针对一组DNS域名进行定期查询,以发现待监控的目标
◼ 查询时使用的DNS服务器由/etc/resolv.conf文件指定;
◼ 该发现机制依赖于A、AAAA和SRV资源记录,且仅支持该类方法,尚不支持RFC6763中的高级DNS发现方式;
◼ 元数据标签:
◆ __meta_dns_name
◆ __meta_dns_srv_record_target
◆ __meta_dns_srv_record_port
Consul基础
Consul简介
◼ 一款基于golang开发的开源工具,主要面向分布式,服务化的系统提供服务注册、服务发现和配置管理的功能
◼ 提供服务注册/发现、健康检查、Key/Value存储、多数据中心和分布式一致性保证等功能
部署(以开发模式为例)
◼ 下载地址
◆ https://www.consul.io/downloads/
◼ 安装
◆ unzip consul_1.9.2_linux_amd64.zip -d /usr/local/bin/
◼ 启动开发者模式
◆ mkdir -pv /consul/data/
◆ consul agent -dev -ui -data-dir=/consul/data/ \
-config-dir=/etc/consul/ -client=0.0.0.0
◼ 正常应该使用server模式
启动Consul时常用的关键参数
查看集群成员
◼ 使用consul members命令
◼ 通过HTTP API进行
◆ ~]# curl localhost:8500/v1/catalog/nodes
在Server上添加其它agent
◼ consul join [options] address …
在agent主机上,设置该agent离开集群并关闭agent
◼ consul leave
基于Consul的服务发现
参考文章Prometheus部署及应用