Chapter 02

数据模型与指标类型

理解 metric name + labels 组成的多维模型,掌握 Counter/Gauge/Histogram/Summary 四种类型的语义与选型,写出规范的指标。

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 组合不同。这就是"多维":你可以事后按 methodstatus 等任意维度聚合切片,无需在采集时预定义。

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 如何选

维度HistogramSummary
分位数计算服务端(histogram_quantile)客户端预计算
跨实例聚合✅ 可以(先 sum bucket)❌ 不可(分位数不可加)
可查任意分位✅ 事后任选❌ 只能看预设的
客户端开销较高(滑动窗口计算)
精度取决于桶粒度较精确
默认选 Histogram

绝大多数场景优先用 Histogram:它能在服务端跨实例聚合再算分位数,这对多副本服务至关重要。Summary 只在需要单实例精确分位、且不需聚合时才考虑。

2.5 指标命名规范

2.6 小结与下一步