第285篇:Telemetry 数据采集与模型驱动
关键词
模型驱动、YANG 模型、Telemetry 数据模型、GPB 编码、数据管道、Kafka 流处理、数据治理、Schema 管理
一、模型驱动 Telemetry 概念
1.1 什么是模型驱动
模型驱动 Telemetry 的核心是用标准 YANG 模型定义采集数据的结构和语义:
模型驱动 vs 传统采集:
传统方式: ┌─ SNMP:OID 取值 → 工程师需查 MIB 才知道含义 ├─ CLI:文本抓取 → 正则提取 → 依赖 CLI 格式 └─ 问题:数据模型与采集绑定,变更困难
模型驱动: ┌─ YANG 模型定义数据 Schema ├─ 设备按模型推送结构化数据(GPB/JSON) ├─ 采集器按 Schema 自动解析 └─ 数据消费端无需关注设备差异
| YANG 模型 → 数据 Schema ▼ ┌──────────────────────────────────┐ └──────────────────────────────────┘ ▼ 采集器→解析器→存储→可视化 | 设备按模型推送数据 { "interface": [ { "name": "40GE1/0/1", "statistics": { "in-bits": 1234567890, "out-bits": 987654321 } } ] | |
|---|---|---|
1.2 YANG 模型的结构
YANG 模型定义数据结构:
module huawei-ifm {
namespace "urn:huawei:params:xml:ns:yang:huawei-ifm";
prefix ifm;
container ifm {
container interfaces {
list interface {
key "name";
leaf name {
type string;
description "Interface name";
}
container statistics {
config false; // RO(只读状态数据)
leaf in-bits {
type uint64;
units "bit";
description "Input bit rate";
}
leaf out-bits {
type uint64;
units "bit";
}
leaf in-discards {
type uint32;
}
leaf in-errors {
type uint32;
}
}
}
}
}
}
Sensor Path 形式:
huawei-ifm:/ifm/interfaces/interface/statistics
对应:YANG 模块:容器/列表/叶子
二、GPB 编码与解码
2.1 GPB 格式
GPB(Google Protocol Buffers)是 Telemetry 最常用的编码格式:
GPB 数据结构定义(.proto 文件):
// telemetry.proto
syntax = "proto3";
message Telemetry {
string node_id = 1; // 设备 ID
string subscription_id = 2; // 订阅 ID
string sensor_path = 3; // 传感器路径
message Collection {
uint64 collection_start_time = 1;
uint64 collection_end_time = 2;
message GPBRow {
uint64 timestamp = 1;
bytes content = 2; // 实际 YANG 数据
}
repeated GPBRow row = 3;
}
Collection collection = 4;
}
// interface_statistics.proto
message InterfaceStatistics {
message Interface {
string name = 1;
message Statistics {
uint64 in_bits = 1;
uint64 out_bits = 2;
uint32 in_discards = 3;
uint32 in_errors = 4;
}
Statistics statistics = 2;
}
repeated Interface interface = 1;
}
2.2 Python 解码示例
# decode_telemetry.py
import grpc
from google.protobuf.json_format import MessageToJson
# 解析 Telemetry 头
def parse_telemetry_header(data):
from telemetry_pb2 import Telemetry
msg = Telemetry()
msg.ParseFromString(data)
return {
"node_id": msg.node_id,
"subscription_id": msg.subscription_id,
"sensor_path": msg.sensor_path,
"collection_start": msg.collection.collection_start_time,
"collection_end": msg.collection.collection_end_time,
"row_count": len(msg.collection.row)
}
# 解析接口统计
def parse_interface_stats(data):
from interface_stats_pb2 import InterfaceStatistics
msg = InterfaceStatistics()
msg.ParseFromString(data)
interfaces = []
for iface in msg.interface:
interfaces.append({
"name": iface.name,
"in_bits": iface.statistics.in_bits,
"out_bits": iface.statistics.out_bits,
"in_discards": iface.statistics.in_discards,
"in_errors": iface.statistics.in_errors
})
return interfaces
三、Telemetry 数据管道架构
3.1 端到端流水线
生产级 Telemetry 数据管道:
| ┌──────────┐ gRPC/PUSH ┌──────────────┐ | ||
|---|---|---|
| 设备集群 网络设备 (1000台) | ──────────────► | 采集层 Telegraf/ Pipeline |
| │ | ||
| ┌─────▼──────┐ | ||
| │ 消息队列 │ | ||
| │ Kafka │ | ||
| │ (缓冲/解耦) │ | ||
| └─────┬──────┘ | ||
| │ | ||
| ▼ ▼ ▼ | ||
| --- | --- | --- |
| ┌──────────┐ ┌──────────┐ ┌──────────┐ | ||
| 实时处理 Flink | 批量处理 Spark | |
| │ │ │ | ||
| ▼ ▼ ▼ | ||
| 时序 DB InfluxDB Timescale | 对象存储 S3/HDFS (历史) | |
| --- | --- | --- |
3.2 Kafka 集成
Kafka Telemetry 数据流:
生产者(Telegraf → Kafka):
[[outputs.kafka]]
brokers = ["kafka-01:9092", "kafka-02:9092"]
topic = "telemetry-raw"
data_format = "json"
ssl_ca = "/etc/telegraf/ca.pem"
消费者(Flink 处理):
-- Flink SQL 实时处理
CREATE TABLE telemetry_source (
node_id STRING,
sensor_path STRING,
interface_name STRING,
in_bits BIGINT,
out_bits BIGINT,
event_time TIMESTAMP(3),
WATERMARK FOR event_time AS event_time - INTERVAL '5' SECOND
) WITH (
'connector' = 'kafka',
'topic' = 'telemetry-raw',
'properties.bootstrap.servers' = 'kafka-01:9092',
'format' = 'json'
);
-- 每分钟聚合
CREATE VIEW interface_avg AS
SELECT
node_id,
interface_name,
TUMBLE_START(event_time, INTERVAL '1' MINUTE) AS window_start,
AVG(in_bits) AS avg_in_bits,
MAX(in_bits) AS max_in_bits,
AVG(out_bits) AS avg_out_bits
FROM telemetry_source
GROUP BY
node_id,
interface_name,
TUMBLE(event_time, INTERVAL '1' MINUTE);
四、数据治理与 Schema 管理
4.1 Schema 注册表
Schema Registry 管理:
| Schema Registry (Confluent / Apicurio) ┌─ Subject: huawei-ifm-statistics ├─ 生产者:写入时校验 Schema ├─ 消费者:自动反序列化 ├─ 兼容性:Backward / Forward / Full └─ 版本管理:Schema 变更留审计 | Version 1: {原始接口统计} Version 2: {+queue stats} Version 3: {rename in-bits→rx-bits} |
|---|---|
兼容性策略: Backward:新 Schema 可读旧数据(推荐) Forward:旧 Schema 可读新数据 Full:同时支持双向兼容
4.2 数据质量监控
Telemetry 数据质量监控项:
1. 完整性(Completeness)
┌─ 采集覆盖率:预期设备 vs 实际推送设备
├─ 字段填充率:必填字段是否非空
└─ 阈值:> 99.9%
2. 时效性(Timeliness)
┌─ 采集延迟:设备采集时间 → 采集器接收时间
├─ 处理延迟:采集器 → 存储
└─ 阈值:< 1 秒(端到端)
3. 一致性(Consistency)
┌─ 同一设备相同 Sensor Path 数据格式一致
├─ Schema 兼容性校验
└─ 跨设备字段单位统一
4. 准确性(Accuracy)
┌─ 值与预期范围校验
├─ 突变检测(in-bits 从 1G → 0 需标记)
└─ 多源交叉验证
质量监控仪表盘:
Grafana 示例:
- 丢失率:推送设备数 / 预期设备数
- 延迟 P99:采集时间 vs 存储时间
- Schema 版本分布
五、模型驱动 Telemetry 的最佳实践
5.1 路径设计
Sensor Path 设计原则:
1. 按数据类型分类
┌─ 高频(100ms):接口统计、队列深度
├─ 中频(1-5s):CPU/内存/BGP 邻居
└─ 低频(30-60s):路由表、ARP 表
2. 按业务重要性
┌─ 关键路径(Core/Spine):全量+高频
├─ 非关键路径(接入 Leaf):核心指标
└─ 带宽受限链路:降低频率
3. 避免冗余采集
┌─ 同一数据不要被多个订阅重复采集
├─ 使用条件路径(Conditional Sensor Path)
└─ 不在重复的粒度
订阅配置组织结构:
subscription core-monitor # 核心设备高频
subscription leaf-standard # Leaf 设备标准
subscription bgp-health # BGP 专项
5.2 设备规模估算
规模估算(以 1000 台设备为例):
采集频率:1 秒推送一次
每次数据量:~10KB(100 个接口统计)
单台设备带宽:10KB/s × 8 = 80Kbps
1000 台总带宽:80Kbps × 1000 = 80Mbps
采集器容量:
每台采集器支撑:500 台设备(含冗余)
CPU:16 core
内存:64GB
需要采集器:2-3 台 (HA)
存储估算:
原始数据:1000台 × 10KB/s × 86400s = ~860GB/天
聚合数据(1 分钟):~14GB/天
保留策略:原始 7 天 + 聚合 30 天 + 月汇总 1 年
总存储:~6TB + ~420GB + ~80GB ≈ 7TB
六、与 NETCONF/RESTCONF 的关系
模型驱动协议对比:
┌──────────────────────────────────────────┐
│ NETCONF / RESTCONF │
│ ┌─ 交互式(Request-Response) │
│ ├─ 用于配置下发和单次查询 │
│ ├─ 同步操作 │
│ └─ 适合:变更配置、采集当前状态 │
│ │
│ Telemetry │
│ ┌─ 流式(Server Push) │
│ ├─ 用于持续监控 │
│ ├─ 异步推送 │
│ └─ 适合:实时监控、趋势分析、异常检测 │
│ │
│ 组合使用: │
│ ┌─ Telemetry 做持续监控 │
│ ├─ 告警触发 → NETCONF 查询详细状态 │
│ └─ 配置变更 → NETCONF/RESTCONF 下发 │
└──────────────────────────────────────────┘
总结
| 关键点 | 说明 |
|---|---|
| 模型驱动核心 | YANG 模型定义数据 Schema |
| 编码格式 | GPB(Protobuf)高效二进制 |
| 数据管道 | 采集器 → Kafka → 流处理 → 存储 |
| Schema 管理 | Registry 管理多版本兼容性 |
| 数据质量 | 完整性/时效性/一致性/准确性 |
| 规模估算 | 1000 台设备约 80Mbps 带宽,7TB 存储 |
思考
- 模型驱动 Telemetry 和传统 CLI/SNMP 采集有什么区别?
- GPB 编码相比 JSON 有什么优缺点?
- Telemetry 数据管道中 Kafka 的作用是什么?
- Schema Registry 的 Backward/Forward/Full 兼容策略有什么区别?
- 如何设计 Telemetry 的 Sensor Path 实现分级采集?
- 如何估算 500 台设备的 Telemetry 带宽和存储需求?
下篇预告:第286篇 - 数据中心网络运维 AI 辅助分析,介绍 AI 在网络运维中的应用、异常检测和智能诊断。