VictoriaMetrics指标流聚合三年回顾与现状(2026)

前言

距离上一篇文章 《VictoriaMetrics的指标流聚合能力应用》 发布于 2023年3月,至今已经整整三年。这三年里,VictoriaMetrics生态发生了翻天覆地的变化——让我们一起来回顾这篇博客提出的问题,看看官方解决了多少,我们的 stream-metrics-route 项目又在今天的位置。


一、三年前我们遇到的问题回顾

让我们快速回顾一下2023年博客中提出的核心问题清单:

#问题2023年状态
P1采集断点问题网络抖动或性能问题导致时间断点,流聚合差值计算被放大
P2巨量数据单点算力极限流聚合无历史状态,性能极优但存在单实例瓶颈
P3分布式任务分配数据分别给哪个算力点计算?
P4同维度指标乱序丢弃多节点计算后同维度指标因时间窗口不同导致后到值被丢弃
P5资源均衡问题分布式计算的资源均衡
P6任务ID维度爆炸流聚合组件会给每条聚合后时间线插入节点ID,横向扩容后维度标签增加

为了解决这些问题,我们开发了 stream-metrics-route,一个基于Go语言的分布式流聚合网关。


二、三年过去了,官方做得怎么样?

我回顾了VictoriaMetrics从v1.86到v1.138.0的 Changelog官方文档,让我们逐个盘点一下官方在这三年里的努力:

2.1 已完美解决 ✅

问题P3、P5:分布式任务分配与资源均衡

官方解决情况: vmagent现在原生支持了 -remoteWrite.shardByURL,配合一致性哈希分片!

从v1.86开始原生支持shardByURL,v1.138.0(2026-03) 更进一步,将数据分发算法从round-robin升级为 一致性哈希(consistent hashing),大幅降低节点变更时的数据重分配比例 Changelog记录

vmagent的哈希分片架构演进:

mermaid
flowchart LR
    subgraph Collect[采集层]
        A1@{ shape: doc, label: "Prometheus Agent 1" }
        A2@{ shape: doc, label: "Prometheus Agent 2" }
    end

    subgraph VMAgent[vmagent 集群]
        direction TB
        B1(vmagent-0)
        B2(vmagent-1)
        B3(vmagent-2)
    end

    subgraph Shard[分片逻辑]
        C@{ shape: diam, label: "一致性哈希" }
    end

    subgraph Storage[存储层]
        D1@{ shape: cyl, label: "vmstorage-0" }
        D2@{ shape: cyl, label: "vmstorage-1" }
        D3@{ shape: cyl, label: "vmstorage-2" }
    end

    A1 -->|remote write| B1
    A2 -->|remote write| B2
    B1 --> C
    B2 --> C
    B3 --> C
    C -->|shard 0| D1
    C -->|shard 1| D2
    C -->|shard 2| D3

    classDef storage fill:#e8f5e9,stroke:#4caf50
    class D1,D2,D3 storage

VictoriaMetrics博客 中给出了具体算法实现的sharding部署建议,配合 VictoriaMetrics Operator 还支持通过 shardCount 直接管理分片。

问题P2:单点算力扩展

现在vmagent支持水平扩展(sharding),可以用 replicas + shardCount 横向扩容,配合HA。详见 Issue #5573讨论

乱序/延迟数据准确性(P1的部分缓解)

v1.112.0(2025-02) 是关键版本,新增了 Aggregation Windows 功能!为histogram和rate计算提供了双窗口缓冲模式,flush不立即执行,而是延迟一个 samples_lag 时间,大幅改善延迟数据的准确性,代价是内存翻倍(同时保持两个聚合窗口)。

Aggregation Windows工作原理:

mermaid
sequenceDiagram
    autonumber
    participant C as 采集端
    participant V as vmagent
    participant S as VictoriaMetrics

    rect rgba(76,175,80,0.1)
        Note over C,V: 数据采集阶段
        C->>V: sample1 @T0
        V->>V: 写入窗口A (current)
    end
    rect rgba(255,152,0,0.1)
        Note over C,V: 延迟数据到达
        C->>V: sample2 @T1 (延迟)
        V->>V: 写入窗口B (previous)
    end
    Note over V: 双窗口并行缓冲
    rect rgba(33,150,243,0.1)
        Note over V,S: 聚合输出
        V->>S: 聚合结果A @T2
        V->>S: 聚合结果B @T3
    end

官方文档参见:Streaming aggregation - Aggregation windows

2.2 仍未解决 ❌

真正的分布式流聚合协调

vmagent的流聚合是单实例内的聚合,多实例之间没有协调机制——如果同一个指标被两个vmagent实例分别聚合,会产生重复或冲突的数据。官方建议通过 without/by 标签来划分实例职责,而不是提供跨实例的分布式协调。

任务ID维度爆炸P6

官方vmagent仍会给聚合后的时间线插入内部标签(如 _aggr 相关标签),但没有类似 stream_task_id 前置标记 + 维度控制的设计。


三、stream-metrics-route的现状与价值

stream-metrics-route核心代码回顾:

文件作用
router.go路由核心,根据relabel规则过滤指标
remotecluster.go双重hashmod调度核心!
remotewrite.goremote write HTTP客户端
kafka.goKafka生产者

核心算法(remotecluster.go):

go
1
2
3
4
5
6
7
8
9
// 双重hashmod调度
hash := sortLabelsHashKey(ts.Labels)
dime := hashMod(r.dimension, hash)  // 第一次hashmod → 任务分区ID
ts.Labels = append(ts.Labels, prompb.Label{
    Name:  "stream_task_id",
    Value: strconv.Itoa(dime),           // 插入stream_task_id标签
})
hashnode = sortLabelsHashKey(filterLabels)  // 第二次hashmod → 节点选择
tmpch := hashMod(r.uplen, hashnode)     // 发往哪个后端writer

stream-metrics-route不可替代性分析

结论: stream-metrics-route在2026年仍然需要!但定位应从"完整的流聚合网关"调整为"指标分发路由网关 + Kafka集成层",核心差异化价值:

  1. 双重hashmod调度 + stream_task_id前置注入: 在网关层就给指标打上 stream_task_id,后续所有节点都按这个ID做一致性路由——这比官方方案更早在数据入口处解决维度控制问题
  2. 多后端异步分发: 支持Kafka和remote write的异步分发,博客中提到的"同步转发阻塞时间窗口"问题得到了解决
  3. Prometheus relabeling原生集成

四、推荐混合架构方案2026

推荐架构:

mermaid
flowchart LR
    subgraph Collect[采集层]
        Prometheus@{ shape: doc, label: "Prometheus Agent 集群" }
        KafkaProducer@{ shape: doc, label: "业务系统指标" }
    end

    subgraph Route[路由层]
        SMR@{ shape: hex, label: "stream-metrics-route" }
    end

    subgraph Aggregate[聚合层]
        vmagent0(vmagent-0)
        vmagent1(vmagent-1)
        vmagent2(vmagent-2)
    end

    subgraph Storage[存储层]
        Victoria@{ shape: cyl, label: "VictoriaMetrics" }
    end

    subgraph Consume[消费层]
        vmalert(vmalert)
        Grafana(Grafana)
    end

    Prometheus --> SMR
    KafkaProducer --> SMR
    SMR -->|task_id=0| vmagent0
    SMR -->|task_id=1| vmagent1
    SMR -->|task_id=2| vmagent2
    SMR --> Kafka@{ shape: cyl, label: "Kafka Topic" }
    vmagent0 --> Victoria
    vmagent1 --> Victoria
    vmagent2 --> Victoria
    Victoria --> vmalert
    Victoria --> Grafana

    classDef route fill:#fff3e0,stroke:#ff9800
    classDef storage fill:#e8f5e9,stroke:#4caf50
    classDef consume fill:#e3f2fd,stroke:#2196f3
    class SMR route
    class Victoria,Kafka storage
    class vmalert,Grafana consume

关键配置建议

vmagent版本要求: >= v1.112.0,启用聚合窗口:

yaml
1
2
3
4
5
6
# stream aggregation配置
- match: 'http_request_duration_seconds_bucket'
  interval: 5m
  without: [instance]
  enable_windows: true   # 关键!启用聚合窗口
  outputs: [rate_sum]

部署: 可参考 deploy.yaml示例


五、演进建议

5.1 短期建议

行动说明
升级vmagent版本到 >= v1.112.0启用 enable_windows: true 改善histogram聚合准确性
评估是否仍需stream-metrics-route如果没有Kafka需求、没有高基数 stream_task_id 控制需求,可以考虑迁移

5.2 中期建议

行动说明
stream-metrics-route仅作为前置路由层保留hashmod任务分配 + Kafka分发
关闭原始指标的持久化只在流聚合后写入storage,减少存储量
补充元数据管理模块博客提到的 ruler-handle-process(动态Record Rule按维度拆分)值得自研或贡献

5.3 长期建议

行动说明
向官方贡献stream_task_id维度控制机制如果这个设计经过生产验证
完善监控指标补充流聚合相关的业务指标(各路由规则的队列深度、分发延迟)

总结

维度结论
博客问题已解决比例约50%(2/4核心问题通过官方升级解决,2/4仍需自研或保持现状)
stream-metrics-route还需要吗?仍然需要,定位调整为"指标分发路由网关 + Kafka集成层"
推荐架构Prometheus → stream-metrics-route → vmagent v1.112.0+ → VictoriaMetrics Storage

参考链接

三年过去,VictoriaMetrics生态已经成熟了很多,但我们仍然需要继续前进!