前言
距离上一篇文章 《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的哈希分片架构演进:
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工作原理:
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.go | remote write HTTP客户端 |
| kafka.go | Kafka生产者 |
核心算法(remotecluster.go):
// 双重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集成层",核心差异化价值:
- 双重hashmod调度 + stream_task_id前置注入: 在网关层就给指标打上
stream_task_id,后续所有节点都按这个ID做一致性路由——这比官方方案更早在数据入口处解决维度控制问题 - 多后端异步分发: 支持Kafka和remote write的异步分发,博客中提到的"同步转发阻塞时间窗口"问题得到了解决
- Prometheus relabeling原生集成
四、推荐混合架构方案2026
推荐架构:
关键配置建议
vmagent版本要求: >= v1.112.0,启用聚合窗口:
# 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 vmagent文档
- Streaming aggregation官方文档
- Changelog 2024-2026
- VictoriaMetrics博客 - vmagent如何工作
- VictoriaMetrics Operator - VMAgent
- Issue #5573 - HA vmagent部署建议
- stream-metrics-route GitHub仓库
三年过去,VictoriaMetrics生态已经成熟了很多,但我们仍然需要继续前进!