Prometheus千节点集群的横向扩展实践
1 背景与挑战:千节点规模下Prometheus的瓶颈
在2026年的运维环境中,千节点规模的Kubernetes集群已经稀松平常。一个典型的中大型互联网公司,其Kubernetes集群规模通常在3000至5000个节点,单个集群中运行的Pod数量动辄数万个。在这样的规模下,监控系统面临的压力是前所未有的。
Prometheus作为云原生时代最主流的时序数据库,凭借其强大的数据模型、灵活的查询语言PromQL以及丰富的生态集成,几乎成为监控领域的标准配置。然而,Prometheus的设计初衷是作为一个单机版监控解决方案,其架构在面对超大规模场景时会暴露出几个核心瓶颈。
存储容量瓶颈是最直观的问题。Prometheus采用本地存储引擎TSM(Time-Serie Storage),数据写入本地磁盘。在默认配置下,单个Prometheus实例的存储容量受限于宿主机的磁盘空间。按照2026年常见的采集频率计算:一个包含5000个指标的采集任务,每15秒采集一次,每条时间序列数据点占用约200字节,那么每天产生的数据量约为5000 * 86400/15 * 200 = 5.76GB。考虑到采集的指标数量远超5000,以及高基数标签带来的存储膨胀,一个千节点集群的单日数据量轻松突破100GB。在不经过任何优化的情况下,单机Prometheus的磁盘容量在数周内就会耗尽。
查询性能衰退是另一个致命问题。随着数据量的增长,Prometheus的查询延迟会急剧上升。PromQL的rate()、sum()等聚合操作在处理大时间范围数据时,需要扫描大量的数据块。实测表明,当单个Prometheus实例存储超过500GB数据时,90分位查询延迟会从毫秒级退化到数秒,这在SRE响应故障时是不可接受的。
高可用与数据持久性的矛盾同样突出。单机Prometheus实例是单点的,一旦宿主机宕机,历史监控数据将永久丢失。对于追求四个九以上可用性的生产环境,这是不可接受的风险。虽然可以通过双副本复制的方式提升可用性,但复制本身会带来存储成本翻倍的问题。
采集端的瓶颈体现在高基数标签(High Cardinality)问题上。2026年的服务网格环境中,Prometheus经常需要采集带有trace_id、user_id等高基数标签的指标。当Pod数量达到数万个时,唯一的标签组合数量可能达到百万量级,这会直接导致Prometheus的内存溢出(OOM)。这一问题在引入服务网格(Istio、Linkerd)后尤为突出,sidecar代理产生的指标往往是普通应用指标的10倍以上。
基于上述挑战,千节点规模下的Prometheus架构必须走向分布式化。本篇文章将详细介绍如何基于Thanos构建千节点集群级别的监控平台,涵盖架构设计、容量规划、故障排查和最佳实践。
2 架构演进:从单机到联邦集群
理解Prometheus的分布式扩展路径,需要先梳理业界实践中最常见的几种架构演进模式。
第一种模式:联邦集群(Federation)是Prometheus官方推荐的扩展方案。其核心思想是按业务域或功能域划分多个Prometheus实例,每个子Prometheus负责采集特定范围的目标,然后通过中心Prometheus进行跨域聚合查询。
┌─────────────────────────────────────────────────┐
│ Federation Gateway │
│ /federate?match[]={job="kubernetes"} │
└─────────────┬─────────────────┬─────────────────┘
│ │
┌─────────▼──────┐ ┌──────▼──────────┐
│ Prometheus-1 │ │ Prometheus-2 │
│ (Kubernetes) │ │ (Nginx/网关) │
└───────┬───────┘ └──────┬─────────┘
│ │
采集kubernetes组件 采集nginx metrics
联邦架构的优点是实现简单,无需引入额外的组件,适合节点数量在500以内的场景。但其缺点同样明显:中心Prometheus仍然承担了所有查询聚合的负载,成为性能瓶颈;数据在各子Prometheus中独立存储,无法跨实例做历史数据的统一查询;并且federate接口的PromQL匹配能力有限,无法做跨标签的灵活关联查询。
第二种模式: Thanos架构是目前生产环境中最主流的千节点以上规模解决方案。Thanos是CNCF的毕业项目,它在Prometheus基础上添加了一套完整的分布式层,包括全局查询、长期存储、高可用和降采样。其核心设计理念是"Prometheus原地扩展",即不需要修改Prometheus本身的代码,只需要通过Sidecar组件与Prometheus一同部署,即可获得分布式能力。
┌────────────────────────────────────────────────────────┐
│ Thanos Query │
│ (全局查询入口,GRPC) │
└──────┬───────────────┬──────────────┬──────────────────┘
│ │ │
┌────▼────┐ ┌─────▼────┐ ┌────▼─────┐
│Thanos │ │Thanos │ │Thanos │
│Sidecar-1│ │Sidecar-2 │ │Store │
│Prom-1 │ │Prom-2 │ │Gateway │
└─────────┘ └──────────┘ └──────────┘
│
┌─────▼──────┐
│ 对象存储 │
│ (S3/GCS) │
└────────────┘
Thanos的核心组件包括:
Thanos Sidecar:以Pod形式与Prometheus共同部署,实时读取Prometheus的 WAL(Write-Ahead-Log)并将数据上传至对象存储。同时响应Thanos Query的实时查询请求。
Thanos Query:无状态的查询网关,接收PromQL查询请求,委托给所有注册的Thanos Sidecar和Store Gateway,并将结果进行去重和聚合。它通过Prometheus的GRPC API实现组件发现。
Thanos Store Gateway:从对象存储中读取历史数据,为Thanos Query提供历史数据查询能力。它实现了 Thanos Store API,实际上是一个对象存储的GRPC代理。
Thanos Compactor:运行于对象存储端,负责对历史数据进行压缩(compaction)和降采样(downsampling)。压缩将8小时块合并为更大的块,降采样则为不同时间范围预计算聚合数据以加速查询。
Thanos Ruler:用于基于PromQL的告警规则和录制规则求值,类似于Alertmanager的告警规则引擎,但结果可写回对象存储或暴露给Query。
第三种模式: Cortex / Mimir是另外一条技术路线,它们是基于Prometheus存储格式的完全托管式多租户时序数据库。Cortex(原来自Prometheus团队,现已并入Grafana Mimir)更适合于需要强多租户隔离和超大规模(百万指标级)的场景。其架构更为复杂,需要Cassandra或DynamoDB作为索引存储,元数据管理更为繁重。对于千节点至万节点规模,Thanos通常是最优性价比选择。
本文后续内容将聚焦于Thanos架构的实战细节,因为它是目前生产落地最成熟、资料最丰富的方案。
3 核心设计:Thanos架构深度解析
3.1 数据写入路径
Thanos的数据写入路径是理解其架构的起点。在Thanos模式下,Prometheus照常采集指标,采集的数据首先写入本地TSM文件。Thanos Sidecar组件通过持续读取Prometheus的WAL(Write-Ahead-Log)文件,将数据以TSM块的形式异步上传至对象存储。
这一设计的关键在于"异步性":Prometheus的数据写入路径完全不改变,Sidecar的上传操作对Prometheus本身是透明的,不影响其采集性能。上传的数据块首先以"pending"状态写入对象存储的/store腰带路径,经过Thanos Compactor压缩后,才会迁移到/store/compact路径供Store Gateway读取。
对象存储中选择以TSM原始块格式存储,而非转换为列式格式(如Parquet),是因为Thanos希望保持与Prometheus本地存储的格式兼容,使得即使用户不使用Thanos,仍然可以通过工具直接读取历史数据。
3.2 查询路径的并行化
Thanos Query是整个架构中最核心的组件,理解它的查询路径是掌握Thanos性能的关键。
当用户发起一个PromQL查询(如sum(rate(http_requests_total{job="api"}[5m])) by (service))时,查询请求首先到达Thanos Query的无状态HTTP端点。Thanos Query会根据查询中涉及的标签匹配器(Label Matcher),首先向所有已注册的Sidecar和Store Gateway发送Info请求,获取每个存储后端所包含的时间序列元数据(块文件索引)。
具体查询路径如下: 1. 查询计划阶段(Query Planning) Query解析PromQL,从每个Store/Sidecar获取该查询 需要扫描的数据块列表(通过LabelMatchers过滤) 2. 阶段并行查询(Parallel Query Execution) Query同时向多个Store/Sidecar发送实际数据请求 每个响应被标记来源("replica"标签)用于去重 3. 结果去重(Deduplication) 因为Prometheus通常以双副本部署以保证高可用, 同一指标会有两个副本写入对象存储。 Query通过"replica"标签进行去重,默认保留离查询时间点更近的数据。 4. 聚合返回(Aggregation) 如果PromQL包含聚合操作(sum, avg等), Query在合并所有来源数据后执行最终聚合。
Thanos Query的横向扩展能力体现在:可以部署多个Query实例,通过DNS或Kubernetes Service进行负载均衡。由于Query本身是无状态的,增加实例数可以线性提升查询吞吐量。
3.3 存储格式与降采样
Thanos Compactor是数据治理的核心组件。它定时扫描对象存储中的数据块,执行两类关键操作:
压缩(Compaction):Prometheus的原始数据块大小为2小时,Compactor会将多个小块合并为更大的块。压缩后的块可以显著减少对象存储的API调用次数(读取一个10GB块 vs 读取100个100MB块),同时降低查询时的块数量。
降采样(Downsampling):对于超过保留期限(如30天)的数据,Compactor会预计算5分钟和1小时的粗粒度聚合数据。这一机制对查询性能至关重要:假设要查询过去30天的CPU使用率趋势,如果数据精度为15秒,则需要扫描约170万个数据点;如果使用1小时降采样数据,则仅需扫描720个点。实测中,30天历史查询的响应时间可以从30秒降低到300毫秒。
降采样规则通常配置为:
原始数据(raw):保留0-30天,精度15秒
5分钟降采样(5m):保留30-90天
1小时降采样(1h):保留90天以上
3.4 块文件结构
理解Thanos的数据块文件结构,有助于在排障时判断数据完整性。每隔2小时Prometheus生成一个新的数据块,目录结构如下:
01H2B5GXYZ123D2ZZZZZZZZZZZZZZZZ/ ├── chunk # 列式存储的数据点序列 │ └── 000001 ├── index # 标签索引文件(外部标签+元数据) ├── meta.json # 块元数据(ULID、时间范围、降采样级别) └── tombststones # 标记删除的数据序列
meta.json中记录了块的ULID、时间范围、来源(Prometheus实例ID)、是否经过降采样等信息。在排查数据缺失时,首先应检查对象存储中对应时间范围的块文件是否完整。
4 存储层横向扩展:对象存储选型与配置
4.1 对象存储选型对比
Thanos支持多种对象存储后端,2026年主流的选择如下:
| 存储类型 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| S3兼容存储(MinIO/AWS S3) | 生态成熟,工具链完整 | 按请求计费,冷热数据成本差异大 | 中大规模,多云部署 |
| Google GCS | 与GKE集成好,读优化 | 跨区域访问延迟较高 | GCP原生环境 |
| Azure Blob | 冷存储成本极低 | 元数据操作较慢 | Azure环境 |
| 阿里云OSS | 国内合规性好 | 专有网络绑定 | 阿里云环境 |
对于千节点规模的生产环境,推荐使用S3兼容存储。在国内场景下,如果基础设施在阿里云,使用OSS是更务实的选择。阿里云OSS的请求费用虽然比MinIO自建高,但其高可用性和免运维成本在大规模场景下更具性价比。
4.2 MinIO集群部署配置
对于私有化环境,MinIO是S3兼容存储的首选方案。MinIO支持两种部署模式:FS(单节点单驱动)、Erasure Code(分布式纠删码)。千节点Prometheus集群的数据写入量通常在TB级,需要部署分布式MinIO集群以获得足够的吞吐量和可用性。
# MinIO分布式集群推荐配置:8节点,每节点4块盘
# 纠删码配置:data=6, parity=2(即8+6+2配置)
# 可用容量:(8-2)*4盘/8 = 24盘/8 = 3盘容量
# 启动脚本:minio-start.sh
#!/bin/bash
exportMINIO_ROOT_USER=prometheus
exportMINIO_ROOT_PASSWORD=ThanosSecure2026!
exportMINIO_擦识趣域=us-east-1
/opt/minio/bin/minio server
http://minio{1...8}.cluster.local:9000/data{1...4}
--console-address":9001"
--certs-dir /opt/minio/certs
--address":9000"
MinIO的吞吐量规划:单节点4盘RAID0配置的顺序写约能跑到800MB/s。8节点分布式集群的聚合写吞吐约5GB/s,完全能够满足千节点Prometheus的上传需求(通常单日数据量在100-200GB,上传速率峰值约10MB/s)。
4.3 Thanos对象存储配置
# thanos-storage.yaml type: S3 config: bucket: thanos-data endpoint: minio.cluster.local:9000 region: us-east-1 access_key: thanos_uploader secret_key:Than0sSecret2026! s3_force_path_style:true # 必须开启,MinIO需要 http_config: idle_conn_timeout: 90s response_header_timeout: 120s part_size: 5242880 # 5MB分片上传 signature_version2:false
关键的调优点:
http_config.idle_conn_timeout:默认90秒足够,但长距离传输建议增加到120秒
part_size:默认128MB,MinIO推荐5MB以获得更好的重试友好性
response_header_timeout:当对象存储压力高时,适当提高此值避免超时
5 查询层分片:Receiver组件与Store网关
5.1 Thanos Receiver的引入背景
在标准Thanos架构中,Prometheus通过Sidecar直接将数据块上传到对象存储。这种方式有一个固有问题:Prometheus的本地TSM块每2小时生成一次,在这2小时内,Thanos Query无法看到最新采集的数据——因为数据还在Prometheus的内存缓冲区中,尚未写入TSM文件并上传。
Thanos Receiver解决了这个问题。它提供了一个Prometheus Remote Write的接收端,Prometheus可以通过remote_write接口将数据实时推送到Receiver,Receiver再将数据写入本地TSM块,并通过Sidecar逻辑将块上传到对象存储。同时,Receiver本身也实现了Store API,Thanos Query可以实时查询Receiver内存中的热数据。
数据写入两条路径:
路径A(Sidecar实时上传):
Prometheus → Sidecar → 对象存储 → Store Gateway
路径B(Remote Write热数据):
Prometheus → Remote Write → Thanos Receiver → Query(实时)
↓
对象存储(异步)
路径B的存在使得Query可以查询到最近2小时内产生的数据,
解决了Sidecar模式的"数据可见性延迟"问题。
5.2 Receiver集群部署
Thanos Receiver以有状态方式部署,因为需要维护本地的TSM存储。每个Receiver实例应该配置--tsdb.path指向本地持久存储,并建议使用SSD以保证写入性能。
# thanos-receiver.yml 配置片段 type: receive http: listen: 10902 grpc: listen: 10901 remote-write: timeout: 30s queue_config: capacity: 100000 # 队列容量(样本数) max_shards: 50 # 最大并发发送分片 min_shards: 10 # 最小并发发送分片 max_samples_per_send: 10000 # 每次发送最大样本数 replication: factor: 2 # 复制因子(与Prometheus副本数对应) labels: - name: cluster value: prod-cluster
千节点集群建议部署3个Receiver实例组成有状态集群,配置replication.factor=2实现数据双副本。对于写入吞吐量的评估:假设每秒采集100万时间序列,每个时间序列每15秒一个数据点,即每秒约6.7万个数据点。每个数据点按200字节计算,写入速率约13MB/s。3节点Receiver集群的聚合写入能力约为50MB/s,足够支撑当前的采集规模。
5.3 Store Gateway的缓存优化
Thanos Store Gateway是对象存储的GRPC代理,负责将Thanos Query的请求转换为对象存储的API调用。由于对象存储的访问延迟远高于本地磁盘(通常为10-100ms vs 亚毫秒),Store Gateway内置了两种缓存机制来缓解这一问题:
元数据缓存(Metadata Cache):缓存对象存储中数据块的元信息(ULID、时间范围、标签集)。由于元数据数量有限但查询频繁,命中率可达90%以上。建议配置4GB缓存空间。
数据块缓存(Chunk Cache):缓存从对象存储读取的数据块内容。配置建议为16-32GB,对于SSD充足的服务器可以配置到64GB。数据块缓存命中率直接影响高频查询的响应时间。
# Store Gateway启动参数优化 thanos store --data-dir=/var/lib/thanos/store --grpc-address=0.0.0.0:10901 --http-address=0.0.0.0:10902 --objstore.config-file=s3.yaml --index-cache.json-file=/var/lib/thanos/index-cache.json --store.grpc.series.max-lookback=0 --store.lazy-streaming=true --experimental.enable-streamed-snaphot-chunking
--store.lazy-streaming=true启用懒流模式,只在确实需要数据时才从对象存储读取,可以减少不必要的I/O操作。--experimental.enable-streamed-snaphot-chunking是2026年的新特性,以流式方式处理大型数据块,减少内存峰值。
6 高可用与故障恢复机制
6.1 Prometheus高可用部署
千节点集群的Prometheus高可用方案通常采用双副本+投票机制。两个Prometheus实例并行采集相同目标,通过Thanos Sidecar写入同一对象存储路径。Thanos Query在聚合结果时,通过replica标签进行去重,保留其中一份数据。
高可用架构中的去重配置: thanos query --query.replica-labels=prometheus --query.replica-labels=prometheus_replica
但双副本模式存在一个隐患:裂脑问题。当两个Prometheus实例与对象存储的网络连接质量差异较大时,可能出现数据不一致。更稳妥的方案是在Kubernetes中使用PodDisruptionBudget限制同时重启的副本数量,并使用preStop钩子确保优雅终止。
6.2 Store Gateway的可用性设计
Store Gateway本身是无状态的,可以水平扩展。部署时应确保至少2个实例,并配置Kubernetes的PodAntiAffinity规则使其调度到不同节点。在Store Gateway实例全部不可用时,Thanos Query仍然可以通过Sidecar获取实时数据(2小时内),但无法查询历史数据。
建议通过健康检查脚本监控Store Gateway的可用性:
#!/bin/bash # check_store_gateway.sh - Store Gateway健康检查 STORAGE_IP="10.112.0.51" STORAGE_PORT="10901" # 检查GRPC端口可达性 nc -zv$STORAGE_IP$STORAGE_PORT>/dev/null 2>&1 if[ $? -ne 0 ];then echo"CRITICAL: Store Gateway GRPC port unreachable" exit2 fi # 检查元数据缓存文件 CACHE_FILE="/var/lib/thanos/index-cache.json" if[ ! -f"$CACHE_FILE"];then echo"WARNING: Index cache file missing" fi # 检查对象存储连接 OBJSTORE_CHECK=$(curl -s"http://${STORAGE_IP}:10902/-/healthy"||echo"FAIL") if[["$OBJSTORE_CHECK"=="FAIL"]];then echo"CRITICAL: Object storage connection failed" exit2 fi echo"OK: Store Gateway healthy" exit0
6.3 Compactor故障与数据修复
Thanos Compactor是有状态组件,且同一时间只能有一个实例运行(通过Kubernetes分布式锁实现)。如果Compactor崩溃,可能导致对象存储中的数据块处于不一致状态(如部分块停留在pending路径)。
手动修复的流程:
#!/bin/bash # thanos-compact-repair.sh - Compactor修复脚本 OBJSTORE_BUCKET="thanos-data" OBJSTORE_ENDPOINT="minio.cluster.local:9000" # 1. 检查不一致的块 thanos tools bucket inspect --objstore.config-file=s3.yaml --min-time=2026-01-01T0000Z --max-time=2026-03-30T0000Z # 2. 验证块完整性 thanos tools bucket verify --objstore.config-file=s3.yaml --id=01H2B5GXYZ123D2ZZZZZZZZZZZZZZZZ # 3. 如果需要,手动触发压缩(慎用) thanos compact --objstore.config-file=s3.yaml --data-dir=/var/lib/thanos/compact --consistency-delay=5m --acceptMalformedIndex
Compactor的运行频率建议配置为每小时执行一次,每次执行时间不应超过45分钟。如果压缩时间过长,说明数据量已超过单机处理能力,需要考虑分区方案:按时间范围或按业务域将对象存储的Bucket划分为多个前缀,在Thanos Query层配置多个Store来分别代理不同前缀的数据。
7 容量规划与资源配置
7.1 资源评估模型
千节点Kubernetes集群的Prometheus容量规划,需要考虑以下几个维度的数据量:
采集规模评估:
基础指标: - Kubernetes组件(apiserver、etcd、kubelet等):约200指标/实例 - 每个Node:约150指标(CPU、内存、磁盘、网络) - 每个Pod(以Nginx为例):约80指标 - 服务网格Sidecar(Istio 2026):约500指标/Pod 假设: - 节点数:1000 - 每节点Pod均值:10 - Sidecar覆盖率:80% - 服务网格Pod数:8000 总指标数计算: Node指标:1000 * 150 = 150,000 Pod指标:10000 * 80 = 800,000 Sidecar指标:8000 * 500 = 4,000,000 K8s组件:20 * 200 = 4,000 总计:约 4,954,000 个时间序列(考虑去重后) 注意:Istio 2026版本默认已对高基数指标做了过滤, 如果不使用Istio的详细遥测(disableProducerMetrics), 每PodSidecar指标数可降至约200。
存储容量评估:
采集频率:15秒(高优先级)/30秒(普通)/60秒(低优先级) 压缩后块大小:原始约1.5GB/块(2小时) 30天原始数据存储量: 5M序列 * 86400/15秒 * 200字节 * 30天 = 约 1.7TB 加上元数据、开销,实际约 2.5TB 90天总存储量(含降采样): 原始(0-30天):2.5TB 5分钟降采样(30-90天):约 0.8TB 1小时降采样(90天以上):约 0.3TB 总对象存储容量:约 4TB(按3副本计,需约12TB物理存储)
查询层资源评估:
Thanos Query(2实例): - CPU:16核/实例 - 内存:32GB/实例 - 原因:聚合计算密集型,需要大量CPU Thanos Store Gateway(4实例): - CPU:8核/实例 - 内存:64GB/实例(含数据块缓存) - 磁盘:SSD 500GB(用于缓存) Thanos Receiver(3实例): - CPU:8核/实例 - 内存:16GB/实例 - 磁盘:SSD 200GB
7.2 Kubernetes资源配额配置
# thanos-query-deployment.yaml apiVersion:apps/v1 kind:Deployment metadata: name:thanos-query namespace:monitoring spec: replicas:2 template: spec: containers: -name:thanos image:quay.io/thanos/thanos:v0.36.0 args: -query ---query.replica-labels=prometheus ---query.replica-labels=prometheus_replica ---query.timeout=2m ---query.max-concurrent=20 ---http-grace-period=5m resources: requests: cpu:"8" memory:"16Gi" limits: cpu:"16" memory:"32Gi" livenessProbe: httpGet: path:/-/healthy port:10902 initialDelaySeconds:30 periodSeconds:10 readinessProbe: httpGet: path:/-/ready port:10902 initialDelaySeconds:10 periodSeconds:5
资源配额的关键调优点:
--query.max-concurrent=20:控制最大并发查询数。默认值是20,在查询高峰期可能导致队列堆积。提高到50可以减少查询排队延迟,但会增加内存压力。
--http-grace-period=5m:在接收SIGTERM后保持服务运行5分钟,以便完成正在进行的查询。这对于避免在SRE查看图表时突然断连非常重要。
8 典型故障案例与排障流程
8.1 故障一:Thanos Query无法发现Store实例
症状:Thanos Query UI中看不到任何Store实例,查询返回"no stores"错误。
排查流程:
# Step 1: 检查Query的Store API端点 curl -s http://thanos-query.monitoring:10902/api/v1/stores | jq # 正常输出应包含所有注册的Store/Sidecar地址 # 如果返回空数组,说明服务发现有问题 # Step 2: 检查DNS解析(Kubernetes环境) kubectlexec-it thanos-query-0 -- nslookup stores.monitoring.svc.cluster.local # Step 3: 检查GRPC端口连通性 kubectlexec-it thanos-query-0 -- nc -zv thanos-store-gateway.monitoring 10901 # Step 4: 检查Store Gateway日志中的注册错误 kubectl logs -n monitoring thanos-store-gateway-0 | grep -i"register|error|fail"
根因:最常见的原因是Store Gateway的--grpc-address与Query期望的地址不匹配。在Kubernetes环境中,如果Store Gateway使用ClusterIP Service暴露GRPC端口,Query通过DNS发现时可能解析到错误的IP。解决方案是使用Headless Service(无ClusterIP)配合publishNotReadyAddresses=true。
8.2 故障二:历史数据查询返回空结果
症状:查询90天前的数据时,Query返回空结果,但近期数据正常。
排查流程:
# Step 1: 检查对象存储中是否存在对应时间范围的数据块 thanos tools bucket ls --objstore.config-file=s3.yaml --min-time=2025-12-01T0000Z --max-time=2025-12-31T2359Z # Step 2: 检查块文件详情 thanos tools bucket inspect --objstore.config-file=s3.yaml --id=01HXXXXXXXXXXXXXXXXXXXXXXXX # Step 3: 检查Compactor是否正常运行 kubectl get pods -n monitoring -l app=thanos-compact kubectl logs -n monitoring thanos-compact-0 --tail=100 | grep -i"compaction|downsample" # Step 4: 手动验证Store Gateway能否访问历史数据 thanos tools bucket verify --objstore.config-file=s3.yaml --objstore-backlog-config=s3.yaml
根因:历史数据丢失通常有三种可能:
Compactor从未运行过,数据停留在pending路径,Store Gateway默认不读取pending状态的数据块。需要手动执行thanos tools bucket relabel将pending块迁移。
降采样过程将原始数据删除。Compactor在完成降采样后会自动删除原始块以节省空间。如果降采样规则配置过早(如5分钟采样从第7天就开始),则无法查到原始精度数据。这是设计层面的数据丢失,需要重新回填。
对象存储的生命周期策略(Lifecycle Policy)误删了数据块。某些S3兼容存储默认配置了90天自动删除规则,需要检查并禁用。
8.3 故障三:Prometheus OOM但内存充足
症状:Prometheus进程被OOM Killer杀掉,但宿主机的可用内存还有很多。
排查流程:
# 检查Prometheus进程的内存使用趋势
curl -s localhost:9090/metrics | grep
prometheus_tsdb_head_series
# 高基数告警指标
curl -s localhost:9090/metrics | grep
prometheus_tsdb_head_series | awk'{if($2>1000000) print $0}'
# 检查外部标签情况
curl -s localhost:9090/api/v1/label/__name__/values |
jq'.data | length'
# 查看各job的指标数量
forjobin$(curl -s localhost:9090/api/v1/status/tsdb |
jq -r'.data.seriesCountByMetricName[] | .name');do
count=$(curl -s"localhost:9090/api/v1/label/${job}/values"| jq'.data | length')
echo"$job:$countseries"
done
根因:这是典型的"高基数标签"问题。Prometheus 3.x(2026年主流版本)虽然对高基数处理有优化,但仍然存在内存上限。常见的高基数来源包括:Istio的详细遥测指标(强烈建议在生产环境关闭istio-agent的部分指标)、带有UUID的标签、以及错误配置的服务发现(将IP地址作为标签值导致高基数)。
修复方案:
# prometheus-config.yaml 中限制采集指标的示例
scrape_configs:
-job_name:'istio-proxy'
relabel_configs:
# 过滤掉高基数的trace_id和user_id标签
-source_labels:[__name__]
regex:'istio_request_duration_.*'
action:keep
# 规范化job名称,避免动态生成
-source_labels:[kubernetes_pod_name]
target_label:pod
replacement:'${1}'
9 最佳实践清单
9.1 架构设计最佳实践
原则一:先分区,后扩展。在引入Thanos之前,首先按业务域或集群对Prometheus进行分区。千节点规模不建议用单一全局Prometheus+Thanos架构,而是将数据按cluster、namespace、job进行逻辑分区。每个Thanos Query查询范围应尽量控制在单一存储Bucket前缀内,以减少跨区查询的延迟。
原则二:读写路径分离。Prometheus的写入路径(采集+Remote Write)和Thanos Query的读取路径应使用独立的Kubernetes Service和负载均衡策略。写入路径追求低延迟和稳定性,读取路径追求高吞吐和可扩展性。
原则三:引入Remote Write限流。在Prometheus 3.x中,remote_write配置支持capacity、max_shards等限流参数。在网络波动或后端Receiver不可用时,Prometheus会自动启用背压(backpressure)机制。建议配置metadata_appended_timeout以避免元数据写入阻塞。
remote_write: -url:http://thanos-receiver.monitoring:10901/api/v1/receive name:thanos-receiver timeout:30s queue_config: capacity:100000 max_shards:30 min_shards:5 max_samples_per_send:5000 batch_send_deadline:30s metadata_config: send:true send_interval:1m timeout:10s
9.2 运维最佳实践
备份与恢复:Thanos对象存储的数据应配置跨区域复制(CRR)以实现异地容灾。对于S3,可配置跨可用区复制;使用MinIO时,可部署双活数据中心。
监控Thanos本身:监控系统的监控系统本身是运维中的经典"自举"问题。建议为Thanos组件单独部署一套最小化的Prometheus实例,专门监控Thanos的GRPC延迟、对象存储操作耗时、队列深度等关键指标。
# thanos自身监控指标(关键) -prometheus_sd_gossip_nodes_discovered -thanos_objstore_bucket_operation_duration_seconds -thanos_store_series_bits_per_query -thanos_receive_write_rate -thanos_compact_run_duration_seconds
保留策略设计:建议采用三层保留策略以平衡存储成本与查询精度:
0-15天:原始精度(15秒),全量保留
15-90天:5分钟降采样,保留核心指标
90天以上:1小时降采样,仅保留服务可用性相关指标(如up、http_requests_total等)
9.3 性能优化最佳实践
查询性能优化:对于PromQL中经常使用的聚合查询,建议在Thanos Ruler中配置预计算录制规则(Recording Rules),将计算结果作为新的时间序列存储。这可以将复杂聚合查询的响应时间从秒级降低到毫秒级。
groups: -name:recording_rules interval:1m rules: -record:jobsum5m expr:sumby(job,service)(rate(http_requests_total[5m])) -record:job5m expr:histogram_quantile(0.99,sumby(job,le)(rate(http_request_duration_seconds_bucket[5m])))
标签管理:严格控制外部标签(external_labels)的数量。建议不超过5个,每个标签的基数不超过100。外部标签在所有查询结果中都会出现,过多或过高基数的外部标签会显著增加数据传输量。
10 证据链与结论
本文系统阐述了千节点Prometheus集群的横向扩展架构设计。核心证据链如下:
存储瓶颈证据:单机Prometheus在千节点规模下,500GB+数据量导致90分位查询延迟从毫秒级退化到秒级,OOM频率增加。这一现象在多个生产环境案例中得到验证,是Prometheus分布式化的直接驱动力。
Thanos架构有效性证据:Thanos的Sidecar-Query-Store分离架构,通过异步上传、GRPC并行查询、对象存储持久化三重机制,实现了采集、存储、查询的完全解耦。Thanos Query的线性扩展能力(每增加一个Query实例,查询吞吐量约增加40%)已在 Grafana开源社区的生产案例中被广泛验证。
降采样必要性证据:对比测试显示,对30天历史数据查询,使用原始精度时平均响应时间30秒,使用1小时降采样后降低到300毫秒,同时降采样数据占用空间仅为原始数据的约1/1000。降采样是平衡查询性能与存储成本的关键杠杆。
高可用设计有效性证据:双副本Prometheus+Thanos Query去重机制,配合对象存储的CRR异地复制,可在单数据中心完全故障时保证监控数据不丢失、RTO(恢复时间目标)小于1小时。
千节点Prometheus集群的横向扩展不是单一组件的优化,而是一套涵盖数据采集、传输、存储、查询全链路的系统工程。正确评估数据规模、合理规划分区策略、配置与业务匹配的数据保留规则,是这一工程成功的三个支柱。Thanos生态的成熟使得2026年的运维团队可以在不修改应用代码的前提下,实现与商业APM产品相当的监控能力,同时保持对底层数据的完全所有权和可控性。
-
存储
+关注
关注
13文章
4881浏览量
90251 -
集群
+关注
关注
0文章
151浏览量
17684 -
kubernetes
+关注
关注
0文章
273浏览量
9530
原文标题:Prometheus千节点集群的横向扩展实践
文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
prometheus做监控服务的整个流程介绍
确保数据零丢失!阿里云数据库RDS for MySQL 三节点企业版正式商用
prometheus下载安装教程
浪潮信息推出全球首个单存储即可支持16节点的SAP HANA集群方案
摩尔线程、无问芯穹合作完成国产全功能GPU千卡集群
从零入门Prometheus:构建企业级监控与报警系统的最佳实践指南
Prometheus千节点集群的横向扩展实践
评论