时序数据库 Prometheus 的基本使用
时序数据库 Prometheus 的基本使用
Prometheus 是一个通过从监控目标上采集 HTTP 数据收集指标数据的监控平台。
数据模型
Prometheus 基本上将所有数据存储为时间序列:属于同一数据指标和同一组标注维度的带有时间戳的数据流。除了存储的时间序列之外,Prometheus 可能会生成临时派生的时间序列作为查询的结果。
指标名称和标签
每个时间序列都由其 _ 名称 _ 和被称为 _ 标签 _ 的可选键值对唯一标识。
指标名称指定了所监测系统的一般功能 (如 http_requests_total - 收到 HTTP 请求总数)。它可能包含 ASCII 字符,数字下划线和冒号。它必须能被正则表达式 [a-zA-Z_:][a-zA-Z0-9_:]* 匹配。
注意:冒号是为用户自定义的规则保留的。exporter 或直接展示的组件都不应使用它们。
标签可以使 Prometheus 支持多维度数据模型:具有相同数据指标名称的标签的任何给定组合都可以标识该数据指标的特定维度实例 (如,使用 POST 方法到 /api/tracks 处理程序的所有 HTTP 请求)。查询语言允许基于这些维度进行过滤和聚合。更改任何标签值,包括添加或删除,都会创建一个新的时间序列。
标签名称可以包含 ASCII 字符,数字和下划线。它必须能被正则表达式 [a-zA-Z_:][a-zA-Z0-9_:]* 匹配。以 __ 开头的标签名称保留供内部使用。
标签值可以包含任何 Unicode 字符。
标签值为空的标签被认为等同于不存在的标签。
另请参阅 命名指标和标签的最佳实践
数据样本
数据样本构成实际的时间序列数据。每个数据样本包括:
- 64 位浮点型数值
- 毫秒精度的时间戳
表示方式
数据指标指定了数据指标名称和一组标签,通常使用如下表示方式来标识时间序列:
// 格式:
<metric name>{<label name>=<label value>, ...}
// 例如:
api_http_requests_total{method="POST", handler="/messages"}这与 OpenTSDB 使用的表示方式相同。
安装、配置 Prometheus
作业和实例
用 Prometheus 的术语来说,可以进行采集数据指标的端点称为 实例,通常对应于单独的进程。具有相同目地的实例的集合 (例如,可伸缩性或可靠性而复制的过程) 称为 作业。
例如,具有四个复制实例的 API 作业:
- job: `api-server`
- instance 1: `1.2.3.4.5670`
- instance 2: `1.2.3.4.5671`
- instance 3: `1.2.3.4.5672`
- instance 4: `1.2.3.4.5673`自动生成标签和时间序列
当 Prometheus 从目标采集数据指标时,它会自动在采集到的时间序列上附加一些标签,以便于识别被采集的目标:
job: 采集数据目标所属的已配置的作业名称。instance: 采集数据目标 URL 的<host>:<port>部分。
如果这些标签中的任何一个已存在于采集的数据中,则行为取决于 honor_labels 配置选项。有关更多信息,请参见 采集配置文档。
对于每个实例的数据采集,Prometheus 按照以下时间序列存储样本:
up{job="<job-name>", instance="<instance-id>"}: 如果实例运行状态良好,则为1;如果采集失败,则为0。scrape_duration_seconds{job="<job-name>", instance="<instance-id>"}: 采集的持续时间。scrape_samples_post_metric_relabeling{job="<job-name>", instance="<instance-id>"}: 数据指标重新标记后剩余样本数。scrape_samples_scraped{job="<job-name>", instance="<instance-id>"}: 目标暴露的样本数scrape_series_added{job="<job-name>", instance="<instance-id>"}: 本次采集新增样本数量。在 v2.10 版本中新增
时间序列 up 对于实例可用性监控很有用。
简单的时间序列选择器
返回数据指标名称为 http_requests_total 的所有时间序列:
http_requests_total返回数据指标名称为 http_requests_total 及给定 job 和 handler 标签的所有时间序列:
http_requests_total{job="apiserver", handler="/api/comments"}返回相同向量的整个时间范围 (在本例中为 5 分钟),使其成为范围向量:
http_requests_total{job="apiserver", handler="/api/comments"}[5m]请注意,无法直接绘制范围向量的表达式结果,而是在表达式浏览器的表格视图 (" 控制台 ") 中查看。
使用正则表达式,您可以只选择 job 标签值与特定模式匹配的时间序列,在本例子中,所有 job 标签以 server 结尾的向量:
http_requests_total{job=~".*server"}Prometheus 中的所有正则表达式都使用 RE2语法。
想要选择除了 4xx 以外的所有 HTTP 状态码,你可以执行:
http_requests_total{status!~"4.."}子查询
返回过去 30 分钟的 http_requests_total 指标的 5 分钟内的平均速率,分辨率为 1 分钟.
rate(http_requests_total[5m])[30m:1m]这是一个嵌套子查询的示例。deriv 函数的子查询使用默认分辨率。请注意,不必要地使用子查询是不明智的。
max_over_time(deriv(rate(distance_covered_total[5s])[30s:5s])[10m:])使用函数、操作符等
返回最近 5 分钟内指标名称为 http_requests_total 的所有时间序列的每秒速率:
rate(http_requests_total[5m])假设 http_requests_total 时间序列都有 job(按作业名称进行划分) 和 instance(按作业的实例进行划分),我们可能希望得到的输出时间序列较少,所以对所有实例的速率进行求和,但仍然保留 job 维度:
sum by (job) (
rate(http_requests_total[5m])
)如果我们有具有两个相同维度标签的不同数据指标,则可以对它们进行二元运算,并且具有相同标签集的两侧的元素都将匹配并传播到输出。例如:此实例表达式为每个实例以 MiB 返回未使用的内存 (在虚构的集群上暴露了有关其运行实例的这些指标):
(instance_memory_limit_bytes - instance_memory_usage_bytes) / 1024 / 1024相同的表达式,但根据应用汇总,可以这么写:
sum by (app, proc) (
instance_memory_limit_bytes - instance_memory_usage_bytes
) / 1024 / 1024如果相同的虚拟集群调度程序对每个实例暴露了以下 CPU 使用率指标:
instance_cpu_time_ns{app="lion", proc="web", rev="34d0f99", env="prod", job="cluster-manager"}
instance_cpu_time_ns{app="elephant", proc="worker", rev="34d0f99", env="prod", job="cluster-manager"}
instance_cpu_time_ns{app="turtle", proc="api", rev="4d3a513", env="prod", job="cluster-manager"}
instance_cpu_time_ns{app="fox", proc="widget", rev="4d3a513", env="prod", job="cluster-manager"}我们可以按应用程序 (app) 和进程类型 (proc) 分组,排名前 3 位的 CPU 用户是这样的:
topk(3, sum by (app, proc) (rate(instance_cpu_time_ns[5m])))假设此指标每个运行实例包含一个时间序列,则可以像这样计算每个应用程序的运行实例数:
count by (app) (instance_cpu_time_ns)