17.9.1 指标基数与TSDB容量估算方法
指标基数与TSDB容量估算方法#
1. 原理与关键概念#
- 时间序列定义:指标名 + 标签集合(name+labels)= 1 条 time series
- 基数(Cardinality):同一指标的不同标签组合数量
- TSDB存储:样本 → WAL(写前日志)→ 内存 Head → Block 文件 + Index
- 影响容量的核心变量:series 数量、抓取频率、保留天数、压缩后样本字节数
原理草图(TSDB写入路径)#
2. 指标基数来源与识别#
- 高基数常见来源
- 动态标签:pod、container、request_id、user_id、ip、url
- 指标爆炸:单指标维度过多
- 服务发现不稳定:实例标签频繁变化
现场检查命令(解释+预期)#
# 1) 查看当前 head 中 series 总量(直接反映基数)
# 预期:输出当前 Prometheus 的 series 数量
curl -s http://localhost:9090/api/v1/query \
--data-urlencode 'query=prometheus_tsdb_head_series' | jq -r '.data.result[0].value'
# 2) 查看 head chunk 数(反映活跃样本量)
# 预期:输出 head chunks 数量
curl -s http://localhost:9090/api/v1/query \
--data-urlencode 'query=prometheus_tsdb_head_chunks' | jq -r '.data.result[0].value'
3. 基数估算步骤(含示例)#
- 梳理指标清单:按 job/exporter 分类统计
- 估算标签维度:为每个指标估计各标签唯一值
- 单指标基数:标签值数量乘积
- 总基数:所有指标基数求和
- 验证与修正:用 Prometheus 自监控指标校验
示例:单指标基数估算#
- 指标:
http_requests_total - 标签:
method(4) * code(10) * instance(20) - 基数:
4 * 10 * 20 = 800 series
可执行示例:统计 Top 指标基数(PromQL)#
# 统计每个指标名当前的 series 数量(Top 10)
topk(10, count by (__name__)({__name__!=""}))
4. TSDB 容量估算方法(含公式与计算)#
S:总 series 数F:抓取频率(秒)R:保留时间(天)B:样本平均字节数(经验值 1.5~2.0 bytes)
计算公式#
samples_per_series = (86400 / F) * Rtotal_samples = S * samples_per_seriesdisk_size ≈ total_samples * B- 额外开销:WAL/Index/Meta 建议 +30%~50%
示例估算(含完整计算)#
S=200,000,F=15s,R=30天,B=1.7samples_per_series = (86400/15) * 30 = 172,800total_samples = 200,000 * 172,800 = 34,560,000,000disk_size = 34.56e9 * 1.7 ≈ 58.8 GB- 预留 50%:
≈ 90 GB
5. 命令化估算示例(脚本+输出)#
#!/usr/bin/env bash
# 文件:/opt/prom-tools/estimate_tsdb.sh
# 用法:./estimate_tsdb.sh 200000 15 30 1.7
S=$1 # series
F=$2 # scrape interval (s)
R=$3 # retention (days)
B=$4 # bytes per sample
samples_per_series=$(( (86400 / F) * R ))
total_samples=$(( S * samples_per_series ))
# 使用 bc 计算容量(GB)
disk_size_gb=$(echo "scale=2; $total_samples * $B / 1024 / 1024 / 1024" | bc)
echo "samples_per_series=$samples_per_series"
echo "total_samples=$total_samples"
echo "disk_size≈${disk_size_gb} GB (未含WAL/Index预留)"
预期输出示例
samples_per_series=172800
total_samples=34560000000
disk_size≈58.80 GB (未含WAL/Index预留)
6. 降低基数与容量治理(含配置示例)#
6.1 Relabel 过滤高基数标签#
# 文件:/etc/prometheus/prometheus.yml
scrape_configs:
- job_name: "kubernetes-pods"
kubernetes_sd_configs:
- role: pod
relabel_configs:
# 删除高变动标签(如 pod_uid)
- action: labeldrop
regex: 'pod_uid|request_id|trace_id'
解释:减少动态标签,降低 series 爆炸。
预期效果:prometheus_tsdb_head_series 下降或增长速度变慢。
6.2 记录规则聚合降维#
# 文件:/etc/prometheus/rules/agg.yml
groups:
- name: http_agg
rules:
- record: job:http_requests_total:rate5m
expr: sum by (job) (rate(http_requests_total[5m]))
解释:使用聚合后的记录规则替代高维原始指标。
7. 安装与工具准备(promtool/tsdb)#
# 安装 Prometheus(含 promtool)
wget -O /tmp/prometheus.tar.gz https://github.com/prometheus/prometheus/releases/download/v2.49.1/prometheus-2.49.1.linux-amd64.tar.gz
tar -zxvf /tmp/prometheus.tar.gz -C /opt/
ln -s /opt/prometheus-2.49.1.linux-amd64 /opt/prometheus
# 检查工具
/opt/prometheus/promtool --version
用途:promtool 用于规则与配置校验,TSDB 工具用于块检查。
8. 排错与验证清单(带命令)#
- 症状:磁盘增长过快
- 检查当前基数
bash curl -s http://localhost:9090/api/v1/query \ --data-urlencode 'query=prometheus_tsdb_head_series' | jq -r '.data.result[0].value' - 症状:Prometheus 重启后数据短期内暴涨
- 检查服务发现是否频繁变更实例标签
promql count by (job) (up) - 症状:WAL 过大/写入延迟
- 查看磁盘与 WAL 目录占用
bash du -sh /var/lib/prometheus/wal df -h /var/lib/prometheus
9. 练习(可验证结果)#
- 基数识别练习
- 用 PromQL 找出 top5 的指标基数
- 期望输出包含指标名与 series 数 - 容量估算练习
- 设S=500k, F=30s, R=15天, B=1.7,计算容量 - 治理验证练习
- 添加 labeldrop 配置后,重启 Prometheus
- 对比prometheus_tsdb_head_series前后变化并记录差值