Prometheus 数据模型详解

Prometheus 数据模型详解

Prometheus 的数据模型是其最核心的设计之一,它决定了指标如何存储、查询和分析。与传统监控系统不同,Prometheus 采用多维时间序列模型(Multi-dimensional Time Series Model),使得监控数据具有极强的灵活性和表达能力。

本文将深入解析 Prometheus 的数据模型,包括 时间序列结构、指标类型、样本格式、标签(Labels)语义、存储机制 等关键概念。


一、核心概念:时间序列(Time Series)

在 Prometheus 中,每一条监控数据都是一条时间序列

什么是时间序列?

一个时间序列是一个由 指标名称 + 标签集 唯一标识的、随时间变化的数值序列。

示例
http_requests_total{job="api-server", instance="192.168.1.10:8080", method="GET", status="200"} 
→ [ (t₀, 10), (t₁, 12), (t₂, 15), ... ]
  • http_requests_total:指标名称
  • {job="api-server", ...}:标签集(Labels)
  • 每个 (timestamp, value) 是一个样本(Sample)

每个唯一的 (metric name + labels) 组合对应一条独立的时间序列


二、数据模型组成要素

Prometheus 的数据模型由以下四个核心部分构成:

组成部分说明
1. 指标名称(Metric Name)标识指标的含义,如 http_requests_total
2. 标签(Labels)键值对,用于添加维度(如 method="GET"
3. 样本(Sample)(timestamp, value) 数据点
4. 时间戳(Timestamp)毫秒级精度的时间戳

三、指标名称(Metric Name)

命名规范

  • ✅ 推荐:小写字母 + 下划线分隔(snake_case)
  • ✅ 语义清晰,反映指标含义
  • ❌ 避免使用特殊字符或空格

常见命名模式

类型示例
Counter(计数器)http_requests_total, job_success_total
Gauge(仪表)memory_usage_bytes, cpu_temperature_celsius
Histogram(直方图)http_request_duration_seconds
Summary(摘要)rpc_duration_seconds

⚠️ Prometheus 会自动为 Histogram 添加 _bucket, _sum, _count 后缀。


四、标签(Labels)——多维模型的核心

标签是 Prometheus 实现多维监控的关键,相当于“维度”或“属性”。

1. 标签的作用

  • 对指标进行切片(Slice)
  • 聚合(Aggregate)
  • 过滤(Filter)
  • 分组(Group)

2. 内置保留标签

Prometheus 自动添加或保留一些特殊标签:

标签名说明
job抓取任务名称(来自 scrape_configs.job_name
instance目标实例地址(如 192.168.1.10:8080
__name__指标名称(内部使用)
leHistogram 的 bucket 上限(less or equal
quantileSummary 的分位数(如 0.99

jobinstance强制标签,几乎所有时间序列都包含。


3. 自定义标签

用户可添加任意自定义标签:

http_requests_total{
  job="api",
  instance="10.0.0.1:8080",
  method="POST",
  handler="/api/users",
  status="500",
  version="v1.2.0"
} 42
常见自定义标签键
标签键示例值说明
methodGET, POSTHTTP 方法
status200, 500响应状态码
handler/api/users请求路径
clusterprod-us集群名称
envprod, staging环境
serviceuser-service服务名
regionus-east-1地域

4. 标签设计最佳实践

原则说明
低基数(Low Cardinality)标签取值应有限(如 status 只有几十种)
语义清晰键名应通用、易懂(避免 tag1, type
避免高基数禁止使用 user_id, order_id, ip, trace_id
统一命名团队内约定标签键(如 env 而非 environment
使用 relabel_configs 清理删除无用标签,减少存储开销

🚫 高基数标签是导致 Prometheus 内存溢出(OOM)和性能下降的最常见原因!


五、样本(Sample)结构

每个样本是一个 (timestamp, value) 对:

  • timestamp:毫秒级 Unix 时间戳
  • value:64 位浮点数(支持整数、小数)

示例

# HELP http_requests_total Total number of HTTP requests
# TYPE http_requests_total counter
http_requests_total{method="GET",status="200"} 1024 1678886400000
http_requests_total{method="GET",status="200"} 1025 1678886415000
  • 第一个样本:时间 1678886400000(2023-03-15 00:00:00 UTC),值 1024
  • 第二个样本:15 秒后,值 1025

六、指标类型(Metric Types)

Prometheus 支持四种核心指标类型,每种类型对应不同的数据语义和使用场景。

1. Counter(计数器)

  • 用途:单调递增的计数器,记录事件发生次数。
  • 特点
    • 只能增加(或重置为 0)
    • 用于 rate(), increase() 计算速率
  • 示例
    http_requests_total{method="GET"} 1024
    

✅ 适用场景:请求总数、错误数、消息发送数


2. Gauge(仪表)

  • 用途:测量当前瞬时值,可增可减。
  • 特点
    • 反映当前状态
    • 无需计算 rate()
  • 示例
    memory_usage_bytes{region="us"} 536870912
    temperature_celsius{sensor="cpu"} 65.3
    

✅ 适用场景:内存使用、温度、队列大小、库存余额


3. Histogram(直方图)

  • 用途:记录事件的数值分布(如请求耗时、响应大小)。
  • 特点
    • 将值分配到预定义的 bucket(桶)
    • 自动生成三个时间序列:
      • <name>_bucket{le="x"}:小于等于 x 的样本数
      • <name>_count:总样本数
      • <name>_sum:所有样本值之和
  • 示例
    http_request_duration_seconds_bucket{le="0.1"} 100
    http_request_duration_seconds_bucket{le="0.5"} 150
    http_request_duration_seconds_bucket{le="+Inf"} 160
    http_request_duration_seconds_count 160
    http_request_duration_seconds_sum 45.6
    

✅ 用于计算分位数:histogram_quantile(0.99, ...)


4. Summary(摘要)

  • 用途:记录事件的分位数分布(如 p50, p95, p99)。
  • 特点
    • 在客户端计算分位数
    • 生成:
      • <name>{quantile="0.5"}:中位数
      • <name>{quantile="0.99"}:99 分位数
      • <name>_count, <name>_sum
  • 示例
    rpc_duration_seconds{quantile="0.5"} 0.01
    rpc_duration_seconds{quantile="0.9"} 0.05
    rpc_duration_seconds{quantile="0.99"} 0.1
    rpc_duration_seconds_count 1000
    rpc_duration_seconds_sum 12.3
    

⚠️ 与 Histogram 对比:

  • Summary:客户端计算,不支持聚合
  • Histogram:服务端计算,支持跨实例聚合(推荐)

七、数据存储格式(TSDB 内部表示)

Prometheus 使用 TSDB(Time Series Database) 存储数据,其内部结构优化了写入和查询性能。

存储单元:Block

  • 数据按 2 小时 block 存储在磁盘
  • 每个 block 包含:
    • chunks/:压缩的时间序列数据块
    • index:倒排索引,支持快速标签查询
    • meta.json:元信息(时间范围、版本等)

内存结构

  • Head Block:当前正在写入的 block,驻留在内存
  • WAL(Write-Ahead Log):持久化未写入磁盘的数据,防止崩溃丢失

八、数据模型总结表

特性说明
模型类型多维时间序列
唯一标识(metric name + labels)
数据点(timestamp, value) 样本
标签作用维度切片、聚合、过滤
核心类型Counter, Gauge, Histogram, Summary
存储机制本地 TSDB,按 block 存储
查询语言PromQL,支持多维操作

九、常见问题与最佳实践

❓ 为什么不能用 user_id 作为标签?

  • 假设有 100 万用户 → 100 万个时间序列
  • 每个序列都要维护内存结构、WAL、索引
  • 导致:
    • 内存爆炸(OOM)
    • 查询变慢
    • 抓取超时

✅ 正确做法:使用 user_count + tier="premium" 等低基数标签


❓ Histogram vs Summary 如何选择?

对比项HistogramSummary
是否支持聚合✅ 跨实例可聚合❌ 不支持
客户端开销低(只需分桶)高(维护滑动窗口)
灵活性高(可在查询时计算任意分位数)低(固定 quantiles)
推荐程度✅ 强烈推荐⚠️ 仅用于无法使用 Histogram 的场景

生产环境优先使用 Histogram


十、总结

Prometheus 的数据模型是其强大分析能力的基础:

“指标名称 + 标签 = 唯一时间序列”

通过合理设计指标名称和标签,你可以构建一个灵活、高效、可维护的监控体系。

黄金法则:

  • ✅ 使用 低基数标签
  • ✅ 优先使用 Histogram 而非 Summary
  • ✅ 避免 高基数爆炸
  • ✅ 统一 命名规范
  • ✅ 利用 PromQL 进行多维分析

掌握 Prometheus 数据模型,是构建云原生可观测性系统的第一步,也是最关键的一步

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值