第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 存储

思考

  1. 模型驱动 Telemetry 和传统 CLI/SNMP 采集有什么区别?
  2. GPB 编码相比 JSON 有什么优缺点?
  3. Telemetry 数据管道中 Kafka 的作用是什么?
  4. Schema Registry 的 Backward/Forward/Full 兼容策略有什么区别?
  5. 如何设计 Telemetry 的 Sensor Path 实现分级采集?
  6. 如何估算 500 台设备的 Telemetry 带宽和存储需求?

下篇预告:第286篇 - 数据中心网络运维 AI 辅助分析,介绍 AI 在网络运维中的应用、异常检测和智能诊断。