2.1 多维数据模型
Prometheus 里一切皆时间序列。每条序列由一个 metric 名和一组 label(标签)键值对唯一标识:
# 格式:metric_name{label1="v1", label2="v2", ...} value
http_requests_total{method="POST", handler="/api/orders", status="200"} 1027
http_requests_total{method="GET", handler="/api/orders", status="200"} 8931
http_requests_total{method="POST", handler="/api/orders", status="500"} 3
上面是同一个 metric http_requests_total 的三条不同序列——因为 label 组合不同。这就是"多维":你可以事后按 method、status 等任意维度聚合切片,无需在采集时预定义。
- Metric Name 指标名
- 描述被测量的内容,如
node_cpu_seconds_total。必须匹配[a-zA-Z_:][a-zA-Z0-9_:]*,冒号:保留给 recording rule。 - Label 标签
- 维度键值对,如
{cpu="0", mode="idle"}。label 名匹配[a-zA-Z_][a-zA-Z0-9_]*,以__开头的是内部保留标签。 - Cardinality 基数
- 一个 metric 下不同 label 组合的数量。基数是 Prometheus 的核心成本——切勿把 user_id、email、请求 ID 等高基数值当 label。
- instance / job
- 抓取时自动附加的两个标签:
job是抓取任务名,instance是被抓取目标的 host:port。 - __name__ 内部标签
- metric 名其实是一个特殊标签
__name__,所以up等价于{__name__="up"},可用正则批量选择指标。 - Exposition Format 暴露格式
/metrics端点返回的纯文本格式,每行一条样本,配# HELP/# TYPE元注释。新一代标准为 OpenMetrics。
把 user_id(百万级)放进 label,会瞬间产生百万条序列,撑爆内存。label 值应是有限枚举:HTTP 方法、状态码、区域、实例名等。
2.2 样本与时间序列
每条序列随时间累积一串 样本(sample),每个样本是 (timestamp_ms, value_float64)。Prometheus 只存 float64 数值——文本信息要靠 label 携带(见下方 info 指标模式)。
# 一条序列在时间轴上的样本
http_requests_total{...} @1718000000 1000
http_requests_total{...} @1718000015 1042
http_requests_total{...} @1718000030 1099
2.3 四种指标类型
Prometheus 客户端库定义了四种指标类型。注意:这只是客户端约定,Server 存的都是普通序列,但类型决定了你该用什么函数去查。
Counter 计数器
只增不减(进程重启会归零)的累计值:请求总数、错误总数、字节总数。你几乎从不直接看它的绝对值,而是用 rate() 看它的增长速率。
# 典型 Counter,名字以 _total 结尾
http_requests_total{status="200"} 128374
node_network_receive_bytes_total{device="eth0"} 9283749283
Gauge 仪表盘
可增可减的瞬时值:内存使用量、温度、队列长度、当前在线连接数。直接看当前值即可。
node_memory_MemAvailable_bytes 4823949312
node_filesystem_avail_bytes{mountpoint="/"} 21474836480
Histogram 直方图
把观测值(如请求延迟)分布到若干 bucket(桶) 里累计计数,用于计算分位数。一个 Histogram 实际暴露三组序列:
# _bucket:累计落入 le(小于等于) 边界的观测次数
http_request_duration_seconds_bucket{le="0.1"} 8412
http_request_duration_seconds_bucket{le="0.5"} 9203
http_request_duration_seconds_bucket{le="1.0"} 9550
http_request_duration_seconds_bucket{le="+Inf"} 9601
# _sum:所有观测值之和 _count:观测总次数
http_request_duration_seconds_sum 4213.7
http_request_duration_seconds_count 9601
之后用 histogram_quantile(0.95, ...) 在服务端估算 P95。分位数计算在服务端聚合,是 Histogram 相比 Summary 的最大优势。
Summary 摘要
与 Histogram 类似,但分位数在客户端预计算,直接暴露 quantile 标签。缺点:客户端算好的分位数无法跨实例聚合。
rpc_duration_seconds{quantile="0.5"} 0.012
rpc_duration_seconds{quantile="0.9"} 0.048
rpc_duration_seconds{quantile="0.99"} 0.31
rpc_duration_seconds_sum 821.4
rpc_duration_seconds_count 67213
2.4 Histogram vs Summary 如何选
| 维度 | Histogram | Summary |
|---|---|---|
| 分位数计算 | 服务端(histogram_quantile) | 客户端预计算 |
| 跨实例聚合 | ✅ 可以(先 sum bucket) | ❌ 不可(分位数不可加) |
| 可查任意分位 | ✅ 事后任选 | ❌ 只能看预设的 |
| 客户端开销 | 低 | 较高(滑动窗口计算) |
| 精度 | 取决于桶粒度 | 较精确 |
绝大多数场景优先用 Histogram:它能在服务端跨实例聚合再算分位数,这对多副本服务至关重要。Summary 只在需要单实例精确分位、且不需聚合时才考虑。
2.5 指标命名规范
- 用基础单位并作后缀:秒
_seconds、字节_bytes,不要用毫秒/KB。 - Counter 以
_total结尾:http_requests_total。 - 用
应用前缀_子系统_名词_单位结构:node_cpu_seconds_total。 - metric 名表达"测什么",用 label 表达"维度",不要把维度塞进名字(❌
requests_get_200_total)。 - info 型元数据用值恒为 1 的 gauge 承载:
build_info{version="1.2.3", go="1.22"} 1。
2.6 小结与下一步
- 序列 = metric 名 + label 组合;label 只放有限枚举,严防高基数。
- 四类型:Counter(累计,配 rate)、Gauge(瞬时)、Histogram(服务端分位)、Summary(客户端分位)。
- 多副本服务优先用 Histogram,命名遵循基础单位 +
_total约定。 - 下一章正式学 PromQL——把这些序列查出想要的答案。