Administrator
Administrator
发布于 2026-11-03 / 0 阅读
0
0

Prometheus 从入门到生产实践(22):Remote Write 与长期存储:队列、兼容与恢复预算

本篇是《Prometheus 从入门到生产实践》第 22 / 24 篇。配置以文中版本与环境前提为准,实验和故障均为教学场景。完整程序、配置及校验范围见配套实验包。

Remote Write、发送队列与长期存储的责任边界

当本地保留期不足、需要跨集群查询或集中保存指标时,可以把样本送往远端存储。Remote Write 解决的是传输路径,不会自动把 Prometheus 变成分布式数据库,也不保证所有接收端具有相同协议、查询和高可用语义。

1. 先把采集、发送、存储和查询分开

典型链路是 exporter → Prometheus 抓取与 WAL → Remote Write 队列 → 接收端写入 → 查询系统。每一步都可能独立失败:本地采集成功时远端仍可能断流,远端接受写入也不代表最终查询入口已经能读到最新数据。

本地 Server 模式通常仍保留自己的 TSDB,用于本地规则和短期排障。Remote Write 不会因为远端数据很多就自动延长本机历史,也不会把远端数据透明接回全部本地查询。

因此验收至少要同时记录本地最新样本、队列积压和远端可查询时间点,而不是只看发送 URL 返回过一次 200。

2. 一份可阅读的发送端配置

下面是独立示意配置。example.test 是文档域名,必须换成授权测试接收端,并按后端要求配置 TLS、身份和租户,不能直接用于生产:

global:
  scrape_interval: 15s
  external_labels:
    monitor_cluster: lab
    replica: a
scrape_configs:
  - job_name: demo
    static_configs:
      - targets: ['127.0.0.1:19100']
remote_write:
  - name: central-lab
    url: https://metrics.example.test/api/v1/write
    remote_timeout: 30s
    queue_config:
      capacity: 10000
      min_shards: 1
      max_shards: 4
      max_samples_per_send: 2000
      batch_send_deadline: 5s
    write_relabel_configs:
      - source_labels: [__name__]
        regex: 'up|ops_demo_.*'
        action: keep

write_relabel 在发送前筛选样本,这里只保留 up 与教学业务指标,不会删除本地已保存数据。它位于外部标签应用之后,与 scrape 阶段的 metric relabel 不同。这个示例保留副本标签,后端如何去重需要明确配置。

配置检查只证明结构和相关语义被接受,不证明域名可达、认证有效或后端完成存储。正式连接前还要核对接收路径:不同产品和单机/集群部署的写入 URL 可能不同。

3. 队列参数控制什么

Remote Write 将发送工作分到 shard。capacity 是每个 shard 的缓冲能力,不是整个系统的可容忍中断时长;max_samples_per_send 影响批量大小,max_shards 限制并发上限,batch_send_deadline 控制低吞吐时的等待。

增加 shard 可能提高吞吐,也可能让接收端限流、连接数和发送端内存更糟。队列内存还与序列缓存、标签和样本类型有关,不能只用“capacity × 8 字节”估算整个进程。

先测正常输入速率和远端实际处理能力,再调参数。若恢复后的发送能力不高于新进入速率,积压就无法被追平。机制和观测方向见 Remote write tuning。

4. 断网后会补发,但不是无限缓存

远端短暂不可用时,系统会根据 WAL 和队列状态尝试重发。中断过久、WAL 截断、磁盘耗尽或明确不可重试的错误都可能导致数据丢失。不同模式与版本的保留策略也不同,因此不能把“可补发”写成“断网多久都不丢”。

观察 samples_pending、发送失败/重试/丢弃计数和最高已发送时间等自监控指标,并结合日志中的 HTTP 状态。具体指标名称、标签和重试条件先在所用版本的 /metrics 与文档中确认。

例如下面的时间差可以作为延迟线索:

time() - prometheus_remote_storage_queue_highest_sent_timestamp_seconds

它不是天然可靠的延迟告警:没有新样本的空闲队列也可能让时间差增长。需要同时确认本地仍有新数据、积压和采集状态,再解释这个值。

5. Remote Write 1.0 与 2.0 要做兼容验证

较新版本支持通过 protobuf_message 选择消息类型,例如 prometheus.WriteRequest 和 io.prometheus.write.v2.Request。后者对元数据、起始时间和直方图等处理有所变化,不是简单换一个 Content-Type 就能保证兼容。本文核对的 Remote Write 2.0 规范仍标为实验状态,采用前需确认发送端与接收端具体实现,而不是假定它已经替换全部现有链路。

切换前核对发送端版本、接收端具体版本与配置、原生直方图和 exemplar 的支持,先用小流量 job 验证写入响应、远端样本和查询语义。不要因为产品宣称“兼容 Prometheus”就认定它接受所有协议变体。规范见 Remote Write 2.0 specification。

启用 Prometheus 自身的 Remote Write receiver 也不是把它改造成通用大规模集中写入平台的默认推荐路线,应按其设计限制选择使用场景。

6. 长期存储的几条架构路线

路线 典型组织方式 选型时必须核对
Thanos Sidecar Prometheus 旁路组件、对象存储、统一查询 块上传时序、压缩参数、副本标签与 Query 去重
Grafana Mimir Remote Write 接入、分布式存储和查询 租户身份、接入限额、HA 去重及运维规模
VictoriaMetrics 单机或集群写入与查询组件 实际写入 URL、复制/去重、查询差异与容量

Thanos 也有 Receive 路线,但 Sidecar 块上传与 Remote Write 不是同一机制。架构选择应阅读各自的 Thanos Sidecar、Mimir 架构 和 VictoriaMetrics 集群说明,再用自己的数据验证,不仅比较压缩率或宣传中的节点数。

7. 一次可控的远端恢复演练

在测试链路持续产生教学请求,记录本地与远端 rate 的结果及最近时间。停止测试接收端一小段时间,观察积压、失败和重试,再恢复并确认积压能被追平。全程记录资源峰值和样本是否缺口。

再测试错误认证或错误租户,确认它们能被明确报警,而不是无限重试掩盖。最后写下“允许多长中断、最多接受多少数据丢失、追平需要多久”的实测预算,并为传输链路本身设置监控。

8. 用吞吐预算解释“恢复了,为什么仍然落后”

假设本地持续摄入每秒一万样本,远端中断十分钟,理想情况下已经积压约六百万样本。恢复后的有效写入能力如果只有每秒一万二,扣除新进入的一万,每秒只有两千能力用来追平,理论上就需要约五十分钟,尚未计算额外重试与序列开销。

因此,连接重新建立和数据恢复到最新是两个里程碑。若接收端只按正常流量配置容量,断流恢复后可能长期落后。应在正常负载之外验证追平余量,并将限流与背压同时纳入实验,而不是只提高发送端 max_shards。

还要检查错误分类。认证不通过、租户不存在、数据格式不支持、样本过旧或标签限制,都可能与网络暂时失败有不同的处理结果。不能用“重试次数增加”证明系统正在恢复,需要核对远端接收计数和实际查询样本。

当后端有多副本或分布式写入路径时,某个入口请求成功也未必等于它承诺的持久化级别,具体语义由后端定义。验收记录应写清被测版本、协议、租户、故障持续时间、积压峰值、追平时间与最终缺口。保存这组信息,后面升级发送端或切换远端产品时才有可比较的基准。


上一篇:高可用架构:双 Prometheus 与 Alertmanager 集群 · 系列目录 · 下一篇:联邦、Agent 与 OpenTelemetry:画清不同数据路径


评论