网络遥测(gNMI / Telemetry)接入与向量化索引实战

网络遥测(gNMI / Telemetry)接入与向量化索引实战

引言

在网络工程领域,"遥测"这个词并不新。

从 SNMP 时代开始,工程师就习惯通过设备暴露的计数器和状态,去理解网络正在发生什么。

但当网络规模扩大到成百上千台设备、控制面和数据面的耦合越来越复杂、业务变化节奏加快之后,"能看到"已经不再等于"能理解"

gNMI 和 Streaming Telemetry 解决的是采集问题:

数据更多、更快、更细。

但它们并没有自动解决另一个更本质的问题------这些数据如何才能成为可被推理、可被检索、可被回溯的工程证据

对于希望真正把 AI 引入网络工程实践的团队来说,遥测不是一个可选模块,而是整个系统的地基:

训练数据来自它,实时推理输入来自它,事故复盘和责任追溯也必须依赖它。

这一章不讨论"概念上的 AIOps",而是从工程实现角度,完整拆解一条现实可落地的路径:
如何把设备端的 gNMI / Streaming Telemetry,转化为结构化时序、事件流,并最终构建可用于相似态检索的向量索引体系。

1、目标与边界

1.1 本章做什么

这一章的目标非常明确,只聚焦三件事:

第一,工程化接入遥测数据

包括 gNMI / Streaming Telemetry 的订阅模型、时间戳处理、collector 设计,以及主流厂商设备在实现上的差异点和坑位。

第二,规范化遥测数据的表达方式

把来自不同厂商、不同设备、不同模型的原始遥测,映射到一个可演进、可审计的统一 schema 中,解决时间对齐、语义不一致和上下文缺失的问题。

第三,将规范化后的遥测构造成向量索引

不是为了炫技,而是为了支持真实工程需求:历史相似态检索、故障候选压缩、AI 模型输入与样本召回。

1.2 本章不做什么

为了避免章节失焦,这里明确不覆盖以下内容:

  • 不深入展开异常检测算法、模型训练或数学推导(这些内容属于后续章节)。
  • 不把向量化描述为"万能解法",也不假设某个模型或数据库能解决一切问题。
  • 不做商业产品选型对比,也不讨论采购与成本问题,只讨论工程能力本身

2、为什么必须工程化遥测,而不是"接上就算了"

2.1 遥测在网络工程链路中的真实位置

在真实网络中,遥测是唯一持续、客观记录网络状态变化的证据来源

配置可以回滚,拓扑可以重建,但事故发生时:

  • 接口 counters 是否异常跳变
  • 队列深度是否持续累积
  • BGP 会话是否频繁 flap
  • 控制面资源是否被打满

这些都只能通过遥测来证明。

如果这些数据只是被画成曲线,或者在告警系统里触发一次性通知,那么它们的价值是被严重低估的。

真正有价值的遥测,必须能够:

  • 被时间对齐
  • 被语义理解
  • 被回溯验证
  • 被模型和检索系统消费

2.2 从 SNMP 到 gNMI:工程能力的变化点

SNMP 时代的问题并不仅仅是"老",而是工程能力的天然上限:

  • 轮询模型导致数据稀疏且不可控
  • 指标粒度固定,无法反映瞬态变化
  • 时间语义模糊,难以对齐跨设备事件

gNMI 和基于 gRPC 的 Streaming Telemetry 在工程上带来的改变主要体现在三点:

第一,数据从拉取变成推送 ,设备开始主动描述自身状态变化。

第二,数据模型结构化 ,OpenConfig 等模型让路径本身携带语义。

第三,时间分辨率显著提升,支持亚秒级采样。

但这并不意味着"接上 gNMI 就万事大吉"。

这些能力如果不被正确建模和规范化,只会让后端系统更复杂。

2.3 为什么单靠 TSDB 不够

传统时序数据库非常擅长做一件事:
回答"某个指标在某段时间内发生了什么变化"。

但网络工程中,很多问题的本质不是单指标,而是状态组合

  • 多个接口同时丢包
  • 控制面负载上升伴随路由震荡
  • 变更后出现与历史事故"高度相似"的整体状态

这些问题更接近于:

"当前网络状态,像不像过去的哪一次?"

这正是向量索引存在的工程意义。

它不是替代 TSDB,而是补齐 TSDB 无法处理的"高维状态相似性"问题。

3、总体架构:一条可落地的工程流水线

3.1 端到端流程概览

一条完整、可演进的遥测到向量索引的流水线,通常包含以下阶段:

设备端遥测 → Collector → 原始存储 → Normalizer → Featureizer → Vectorizer → Vector Store → 上层应用

每一层都有清晰职责,不能混用,也不能省略

3.2 各模块的工程职责

Collector

负责 gNMI 解码、订阅管理、时间戳处理、最基础的去重与流控。

Raw Store

保存未经处理的原始遥测数据,通常采用冷热分层:

热路径用于短期分析,冷路径用于审计、回放与训练。

Normalizer

解决厂商差异、字段对齐、时间对齐问题,把原始遥测映射为统一语义模型。

Featureizer

将连续时序和事件流转化为"状态片段",构造可用于相似性判断的特征。

Vectorizer

将特征映射为固定维度向量,并附带完整的元数据指针。

Vector Store

提供高效的近邻检索能力,支持时间过滤、标签过滤和回溯。

3.3 非功能需求必须一开始就设计

很多遥测系统失败,并不是功能不够,而是忽略了非功能需求:

  • 时延目标是否明确
  • 数据是否可审计、可回放
  • schema 是否支持演进
  • 大规模数据是否可治理

这些问题如果在系统上线后才考虑,几乎一定要推翻重来。

4、Collector 实战:gNMI 接入不是"连上就行"

4.1 gNMI 订阅模型的工程含义

从表面看,gNMI 的订阅类型只是配置选项:

  • SAMPLE
  • ON_CHANGE
  • TARGET_DEFINED

但在工程上,它们代表的是完全不同的数据语义

4.2 时间戳:遥测系统的第一条生命线

一个非常常见、也非常危险的假设是:

"设备发来的时间戳就是准确的。"

在生产网络中,这个假设经常不成立:

  • 设备本地时钟漂移
  • 不同板卡采样周期不同
  • 传输链路引入抖动

因此,Collector 必须同时保留:

  • device timestamp
  • collector ingest timestamp

并在后端根据漂移情况决定采用哪一个。

时间一旦错位,向量化和相似态检索就会建立在错误的因果关系之上。

4.3 Collector 的工程级要求

一个可用的 Collector,至少要具备以下能力:

  • 并发管理大量订阅
  • 支持断连重试与幂等恢复
  • 支持回放原始 protobuf
  • 支持滚动升级而不中断采集

这不是"锦上添花",而是长期可运维的前提。

5、Normalizer:语义统一与时间对齐的工程细节

5.1 为什么 Normalizer 是整条链路里"最脏、最累、却最关键"的一层

如果说 Collector 是体力活,Featureizer 是经验活,那么 Normalizer 就是那种没人爱做,但做不好一切都会塌掉的苦差事。

在现实网络中,你几乎不可能遇到"干净"的遥测数据:

  • 同一个指标,不同厂商字段名不同
  • 同一个字段,不同版本语义不完全一致
  • 同一时间点,不同设备时间戳不可比
  • 同一个对象,在不同模型下路径结构不同

Normalizer 的职责不是"清洗数据",而是完成一件更严格的事情:

把"厂商实现"还原成"工程语义"。

只要这一步失败,后续 Featureizer 和向量化做得再漂亮,都是在堆沙子。

5.2 语义统一不是字段映射,而是"语义对齐"

一个非常常见的错误,是把 Normalizer 理解为:

path A → path B

field_x → field_y

这种字段级映射,只解决了最表层的问题。

真正的难点在于,很多指标在不同设备上的"工程含义"并不完全相同,例如:

  • interface counters 是否包含子接口
  • queue depth 是瞬时值、平均值,还是滑动窗口
  • CPU 利用率是否包含 control-plane 以外的线程

因此,一个工程级 Normalizer 至少要做三层对齐:

第一层,结构对齐

把不同模型、不同路径,映射到统一的逻辑对象,例如"接口""邻居""队列"。

第二层,语义对齐

明确每一个字段代表的工程含义,而不仅是名字相同。

第三层,可比性标注

当某些指标在不同设备之间天然不可比时,必须显式标注,而不是假装一致。

5.3 时间对齐:比你想象中更容易制造假因果

时间对齐是 Normalizer 中最容易被低估、但破坏性极强的一部分。

在生产网络中,以下情况几乎一定存在:

  • 不同设备 NTP 漂移不同
  • 设备上报时间是"采样时间"还是"发送时间"
  • 不同板卡、不同子系统采样周期不同

如果你直接用 device timestamp 去拼跨设备状态,很容易得到一个看似合理、实际上完全错误的因果链

工程上常见的做法是:

  • 同时保留 device time 和 ingest time
  • 对关键设备做漂移评估
  • 在 Normalizer 中统一生成"工程时间轴"

这个"工程时间轴"不追求绝对精确,但必须在整个系统内自洽

5.4 Normalizer 的输出契约

一个合格的 Normalizer 输出,必须满足以下条件:

  • 每一条数据都有明确的工程对象归属
  • 每一个字段都有稳定、可演进的语义定义
  • 每一个时间戳都有明确来源说明
  • 可以在未来版本中向后兼容

Normalizer 的输出,不是给人看的,而是给后续所有系统长期依赖的"事实层"

5.5 设计统一 schema 的原则

  • 最小可用性(Minimally Viable Schema):第一次不要把所有可能字段都纳入,先覆盖关键指标(interface counters、queue depth、cpu/mem、BGP adj/state)。
  • 扩展性(Extensible Tagging):每条时序都应至少有 {device_id, role, site, region, vendor, software_version, topo_node_id} 这类标签。
  • 语义保持(Preserve Semantics):对不同厂商的 semantically equivalent 字段不要盲目合并(例如不同厂商对 "drops" 的定义可能不同),需要在 metadata 中注明源解释。

5.6 时间对齐与窗口策略

  • 事件 vs 指标:把"事件"视为瞬时发生(interface down、config-change),而"指标"应有固定采样窗口(rate, p50, p95)。
  • 对齐策略:
    • 固定窗口(例如 10s):适用于 rate 计算与短周期检测。
    • 滑动窗口(例如 60s 滑动步长 10s):提高平滑性与短时突发感知。
  • Missing data 处理:对短时间丢失使用插值或前向填充(仅在度量合理时),否则标注为缺失以避免误判。

5.7 标准化字段示例(JSON schema 片段)

下面示例展示了一个标准化后的 telemetry event(简化后):

复制代码
{

  "timestamp": "2025-12-16T08:30:12.123Z",

  "device_id": "leaf-12",

  "vendor": "cisco",

  "site": "dc1",

  "role": "leaf",

  "path": "/interfaces/interface[name=Ethernet1]/state/counters",

  "values": {

    "in_octets": 123456789,

    "out_octets": 234567890,

    "in_unicast_pkts": 123400,

    "out_unicast_pkts": 234500,

    "in_errors": 12,

    "out_errors": 0

  },

  "meta": {

    "software_version": "17.3.1",

    "time_source": "device",

    "raw_message_id": "abc123def"

  }

}

这个结构中的 meta 和 tags,将直接成为后续向量数据库中的 Filter 索引字段。

5.8 特殊处理:BGP 与路由表的规范化

  • BGP RIB/NLRI 是高基数(prefix count 巨大)的数据,需要做两层处理:
    • 对控制面语义(peer up/down、route withdrawal)做事件化记录;
    • 对实际 prefix 集合做 summary(prefix count per peer, prefixes learned, bestpath changes)而非单纯存全量 prefix(除非有特殊需求并且有能力存储)。
  • 对 prefix 的历史判定要保留 origin AS、communities、local-pref 等关键 attributes。

对于 BGP Flap 等复合震荡,Normalizer 只负责记录原子事件,真正的'震荡状态判定'将交由下一节 Featureizer 处理。

6、Featureizer:把"遥测噪声"压缩成可推理的工程状态

6.1 Featureizer 的真实角色:不是算特征,而是"切状态"

在绝大多数工程团队中,"特征工程"这个词很容易被误解为算法问题,仿佛只要喂给模型足够多的指标,模型自然会学会一切。

在网络遥测体系里,这种思路几乎一定失败。

原因很简单:
遥测本身不是"样本",而是连续、嘈杂、语义混杂的状态流。

Featureizer 的首要职责,不是计算统计量,而是完成一件更基础、也更工程化的事情:

把连续时间上的遥测流,切分成"可被比较、可被召回、可被复用"的状态片段(state slice)。

只有当"状态"被明确切出来,后续的向量化、相似性检索、因果回放才有意义。

6.2 为什么"按指标算特征"在网络里行不通

一个常见但危险的实现方式是:

  • 每个指标算 avg / max / min / p95
  • 固定时间窗口(比如 5 分钟)
  • 所有指标拼成一个大向量

这种方式在日志、业务监控中尚且勉强可用,但在网络工程中会迅速失效,原因包括:

第一,网络问题是强相关、多指标联动的

单个接口的丢包并不说明问题,但如果同时出现:

  • 队列积压
  • ECMP 链路负载失衡
  • 上游 BGP 邻居 flap

那才是一个"状态"。

第二,固定时间窗口会切断因果链

真实故障往往表现为:

  • 某个指标先异常
  • 若干秒或几十秒后,另一些指标跟随变化

粗暴的窗口统计会直接抹平这种时序关系。

第三,不同遥测类型本就不该被同等对待

SAMPLE 型指标和 ON_CHANGE 型事件,语义完全不同,却常常被强行拼在一起。

6.3 Featureizer 的第一原则:以"状态变化"为中心,而不是时间

一个工程可用的 Featureizer,必须遵循一个核心原则:状态片段的边界,应由"网络本身的物理状态变化"决定,而非人为划定的"钟表时间"。 例如,接口 Flap 导致的路由震荡可能持续 13 秒,那么这 13 秒就是一个完整的状态片段。如果强行用 1 分钟的固定窗口切割,这个因果链就会被切碎在两个不同的时间窗里,导致模型无法识别。

在实践中,这通常通过三类触发条件来实现:

  • 事件触发:接口 up/down、邻居状态变化、协议状态迁移
  • 阈值触发:速率、利用率、队列深度越过工程阈值
  • 结构触发:拓扑、ECMP 组、策略生效路径发生变化

当触发发生时,Featureizer 会:

  1. 回溯一段"前置稳定期"
  2. 向前覆盖一段"后续演化期"
  3. 形成一个完整的状态切片

这比任何固定窗口都更贴近工程现实。

6.4 状态切片的最小工程单元

一个"状态片段"不是随意拼凑的数据块,而是一个有明确边界和语义的对象,至少应包含:

  • 时间范围
    • 起点、终点
    • 是否完整、是否截断
  • 参与对象
    • 设备
    • 接口 / 邻居 / VRF / 实例
  • 关键指标轨迹
    • 原始序列或降采样序列
  • 触发原因
    • 事件 / 阈值 / 结构变化
  • 上下文引用
    • 拓扑快照
    • 配置版本指针

Featureizer 的输出,应该已经是一个"工程事件级对象",而不再是散乱的点。

6.5核心原则:将工程经验固化于 Featureizer。

**把工程经验固化进 Featureizer,而不是模型里,**一个成熟的 Featureizer,往往隐含了大量工程经验,例如:

  • 接口 flap 前后,重点关注哪些指标
  • BGP 会话异常时,哪些 counters 有判别力
  • 控制面压力问题,CPU 之外必须联动哪些遥测

这些经验不应该寄希望于模型自动学会,而是应该被明确编码进 Featureizer 的规则中。

原因只有一个:**工程经验是稀缺且可解释的,而模型权重不是。**Featureizer 是把"工程直觉"系统化、可复制的关键位置。

6.6 Featureizer 与上游 Normalizer 的边界

需要特别强调的是:

  • Featureizer 不解决厂商差异
  • Featureizer 不修正字段语义
  • Featureizer 不做时间对齐基础工作

这些都是 Normalizer 的职责。

Featureizer 假定输入已经是:

  • 语义一致的
  • 时间可对齐的
  • 上下文可引用的

一旦 Featureizer 被迫去"补救"这些问题,系统复杂度会指数级上升。

7、Featureizer 输出的工程价值,而不仅是模型输入

7.1 不做向量,也依然有价值

即便你暂时不做向量化,Featureizer 的输出依然可以直接支撑多种工程能力:

  • 故障候选状态的自动聚合
  • 人工排障时的状态对齐视图
  • 事故复盘中的"关键阶段"标注

很多团队低估了这一层,直接把遥测送进模型,结果是:

  • 不可解释
  • 不可复盘
  • 不可复用

7.2 Featureizer 是"工程规模化"的关键门槛

在小规模网络中,资深工程师可以靠经验脑补状态变化。

但在大规模网络中:

  • 不可能靠人脑记住所有组合
  • 不可能每次事故都从零开始看曲线

Featureizer 的存在,本质上是在回答一个问题:

如何把少数人的工程经验,扩展成系统能力。

7.3、为向量化做准备:Featureizer 必须留下"可追溯性"

在进入向量化之前,Featureizer 还有一个不可妥协的要求:

任何被压缩、被聚合的特征,都必须能追溯回原始遥测。

这意味着:

  • 特征 → 状态片段 → 原始遥测
  • 每一层都有明确指针
  • 没有"黑盒统计值"

否则,一旦向量检索结果被用于决策,却无法解释"为什么像",系统将无法在工程组织中生存。

8、向量化:从状态片段到可检索空间

8.1 为什么要向量化,而不是"再多写点规则"

到这里,很多工程师会自然地产生一个疑问:

既然 Featureizer 已经切出了状态,Normalizer 也统一了语义,为什么还非要搞向量?

原因是:规则只能回答"是不是这个问题",但向量可以回答"像不像某类问题"。

在真实网络中,你经常面对的是:

  • 没见过的故障形态
  • 多种问题叠加
  • 边界条件触发的非典型表现

向量化的价值,不在于"预测",而在于压缩搜索空间

8.2 向量化的输入,不是指标,而是"状态描述"

一个严重的设计错误是:
直接把指标数值送进向量模型。

正确的向量化输入,应该来自 Featureizer 输出的"状态片段",例如:

  • 指标变化趋势(上升、下降、震荡)
  • 多指标之间的相对关系
  • 状态持续时间与阶段划分
  • 触发事件的类型组合

换句话说,向量描述的不是"网络长什么样",而是:

"网络正在经历什么"。

8.3 固定维度不是目的,可比较性才是

向量化并不要求你使用多复杂的模型。

在工程实践中,更重要的是:

  • 同类状态映射到相近空间
  • 不同类状态能被明显区分
  • 向量随 schema 演进而可重算

很多团队一开始就追求"高维""深模型",结果却发现:

  • 向量不可解释
  • 版本一升级,全量失效
  • 历史数据无法对比

工程上,稳定性永远优先于炫技

8.4 元数据不是附属品,而是向量的一部分

一个可用的向量对象,永远不只是一个 float 数组,它必须绑定完整元数据:

  • 状态片段 ID
  • 时间范围
  • 设备 / 拓扑标签
  • 配置版本指针
  • Featureizer 规则版本

否则,向量一旦被命中,你将无法回答最基本的问题:"这到底是哪一次网络状态?"

向量不仅是数值,必须携带元数据(Metadata)。

9、向量索引在真实网络中的使用方式

9.1 相似态检索,而不是"智能诊断"

在真实工程中,向量索引最常见、也最可靠的用途是:

给工程师一个"历史参考集合"。

例如:

  • 当前状态最像过去哪 5 次
  • 那些状态最终是如何演化的
  • 当时采取了什么操作

这不是让系统"替你下结论",而是让工程师不必从零开始思考

9.2 向量索引如何嵌入排障流程

一个典型的使用方式是:

  1. 当前状态被 Featureizer 切片
  2. 向量化后进入索引
  3. 返回 Top-K 相似历史状态
  4. 关联当时的变更、告警、处理记录
  5. 人工或半自动决策

注意,向量索引永远不应该是最终裁决者

9.3 、为什么向量索引必须支持时间与标签过滤

如果你的向量检索只能"全库搜最近邻",那它在工程中会迅速失效。

必须支持的能力包括:

  • 按时间范围过滤(只看最近一年)
  • 按网络域过滤(只看某个 DC / 区域)
  • 按设备类型过滤
  • 按配置版本过滤

否则,检索结果会充满"历史垃圾相似态",毫无参考价值。

10、把这一整套能力接入真实工程体系

10.1 不要从"全量接入"开始

一个成熟但不讨喜的建议是:

先从一类问题、一个域、一个场景做起。

例如:

  • 只做接口稳定性
  • 只做 BGP 会话问题
  • 只覆盖一个数据中心

否则,遥测、特征、向量会在第一周就把系统压垮。

10.2 成功与否的真正判断标准

这套体系是否成功,不取决于:

  • 模型多复杂
  • 指标多全面
  • 数据量多大

而只取决于一个问题:

事故发生时,它有没有真的帮工程师少走弯路。

结语:

**遥测不是数据问题,而是工程认知问题,**gNMI、Streaming Telemetry、本身只是工具。

真正困难的,是:

  • 如何定义"状态"
  • 如何统一"语义"
  • 如何保存"经验"
  • 如何让系统随着网络一起成长

如果你认真走完了这一章描述的工程路径,那么你已经具备了一个关键能力:

把网络从"只能看曲线",变成"可以被回忆、被比较、被学习的系统"。

这不是一蹴而就的事,但这是所有网络智能化的起点。

(文:陈涉川)

2025年12月16日

相关推荐
薛不痒4 小时前
机器学习算法之逻辑回归下
人工智能·机器学习·逻辑回归
松果财经4 小时前
「直通」英伟达,蓝思科技补齐AI算力布局又一块拼图
人工智能
睿观·ERiC4 小时前
跨境电商合规预警:Keith 律所 TRO 诉讼(25-cv-15032)突袭,奇幻插画版权风险排查指南
大数据·人工智能·跨境电商
SmoothSailingT4 小时前
C#——单例模式
开发语言·单例模式·c#
与遨游于天地4 小时前
接口与实现分离:从 SPI 到 OSGi、SOFAArk的模块化演进
开发语言·后端·架构
醇氧5 小时前
Spring Boot 应用启动优化:自定义事件监听与优雅启动管理
java·开发语言·python
请叫我初学者5 小时前
Java学习心得、项目流程(一个Java实习3月的菜鸟)
java·开发语言·intellij-idea·java实习心得
小小8程序员5 小时前
Premiere Pro 2025 让视频创作效率翻倍最新版本下载安装教程
人工智能
小苑同学5 小时前
PaperReading:《GPT-4 Technical Report》
人工智能·语言模型
代码游侠5 小时前
学习笔记——线程
linux·运维·开发语言·笔记·学习·算法