Skip to content

网络硬件深度解析

课程概述

本教程全面讲解网络硬件的工作原理,从网卡架构到交换机转发机制,从RDMA技术到SmartNIC,帮助你深入理解网络性能优化和数据中心网络架构。

学习目标

  • 理解网卡(NIC)的硬件架构
  • 掌握交换机和路由器的工作原理
  • 深入了解RDMA零拷贝技术
  • 学会网络卸载(TSO/LRO/RSS)
  • 掌握网络性能测试方法

1. 网卡架构

1.1 NIC内部结构

┌─────────────────────────────────────────────────────────────┐
│              网卡架构(Network Interface Card)               │
└─────────────────────────────────────────────────────────────┘

完整网卡架构:
┌───────────────────────────────────────────────────────────┐
│                    Network Interface Card                 │
│                                                           │
│  ┌─────────────────────────────────────────────────────┐ │
│  │  主机接口                                            │ │
│  │  ┌──────────────────────────────────────────────┐  │ │
│  │  │  PCIe Interface (x8/x16)                     │  │ │
│  │  │  - DMA引擎                                    │  │ │
│  │  │  - MSI-X中断                                  │  │ │
│  │  └──────────────┬───────────────────────────────┘  │ │
│  └─────────────────┼──────────────────────────────────┘ │
│                    │                                     │
│  ┌─────────────────▼──────────────────────────────────┐ │
│  │  网卡控制器 (NIC Controller)                        │ │
│  │  ┌──────────────────────────────────────────────┐ │ │
│  │  │  CPU核心 (ARM/MIPS)                          │ │ │
│  │  │  - 固件执行                                   │ │ │
│  │  │  - 数据包处理                                 │ │ │
│  │  └──────────────────────────────────────────────┘ │ │
│  │                                                    │ │
│  │  ┌──────────────────────────────────────────────┐ │ │
│  │  │  内存控制器                                   │ │ │
│  │  │  ┌────────────┐  ┌────────────┐             │ │ │
│  │  │  │ DDR缓冲区  │  │ 包描述符   │             │ │ │
│  │  │  │ (数据)     │  │ (元数据)   │             │ │ │
│  │  │  └────────────┘  └────────────┘             │ │ │
│  │  └──────────────────────────────────────────────┘ │ │
│  │                                                    │ │
│  │  ┌──────────────────────────────────────────────┐ │ │
│  │  │  多队列引擎 (RSS/VMDq)                        │ │ │
│  │  │  ┌───┐┌───┐┌───┐┌───┐                       │ │ │
│  │  │  │RxQ││RxQ││RxQ││RxQ│  接收队列(多个)        │ │ │
│  │  │  └───┘└───┘└───┘└───┘                       │ │ │
│  │  │  ┌───┐┌───┐┌───┐┌───┐                       │ │ │
│  │  │  │TxQ││TxQ││TxQ││TxQ│  发送队列(多个)        │ │ │
│  │  │  └───┘└───┘└───┘└───┘                       │ │ │
│  │  └──────────────────────────────────────────────┘ │ │
│  │                                                    │ │
│  │  ┌──────────────────────────────────────────────┐ │ │
│  │  │  卸载引擎 (Offload Engines)                   │ │ │
│  │  │  - Checksum计算/验证                          │ │ │
│  │  │  - TSO/LRO (TCP分段/聚合)                     │ │ │
│  │  │  - VLAN插入/剥离                              │ │ │
│  │  │  - 加密/解密 (IPsec)                          │ │ │
│  │  └──────────────────────────────────────────────┘ │ │
│  └────────────────────┬───────────────────────────────┘ │
│                       │                                 │
│  ┌────────────────────▼───────────────────────────────┐ │
│  │  MAC (Media Access Control)                        │ │
│  │  - 帧封装/解封装                                    │ │
│  │  - 流量控制 (Pause Frames)                         │ │
│  │  - 统计计数器                                       │ │
│  └────────────────────┬───────────────────────────────┘ │
│                       │                                 │
│  ┌────────────────────▼───────────────────────────────┐ │
│  │  PHY (Physical Layer)                              │ │
│  │  - 信号编码/解码 (64b/66b)                         │ │
│  │  - 串行化/反串行化                                  │ │
│  │  - 时钟恢复                                         │ │
│  │  - 均衡/预加重                                      │ │
│  └────────────────────┬───────────────────────────────┘ │
│                       │                                 │
│                  ┌────▼────┐                            │
│                  │光模块/RJ45│                            │
│                  └─────────┘                            │
└───────────────────────────────────────────────────────────┘

数据包接收流程:
┌──────────────────────────────────────────┐
│  1. 物理层                                │
│     物理信号 → 数字比特流                 │
│     ↓                                    │
│  2. MAC层                                │
│     帧同步 → 前导码剥离 → CRC校验         │
│     ↓                                    │
│  3. 包分类 (RSS哈希)                      │
│     五元组哈希 → 队列选择                 │
│     ↓                                    │
│  4. DMA传输                              │
│     包数据 → 主机内存                     │
│     描述符 → 环形缓冲区                   │
│     ↓                                    │
│  5. 中断通知                              │
│     MSI-X中断 → CPU处理                  │
└──────────────────────────────────────────┘

1.2 网卡队列与RSS

┌─────────────────────────────────────────────────────────────┐
│              RSS - Receive Side Scaling                      │
└─────────────────────────────────────────────────────────────┘

单队列问题(传统):
┌────────────────────────────────────┐
│  网卡                               │
│  ┌──────────┐                      │
│  │ 单个队列  │  所有包进同一队列     │
│  └─────┬────┘                      │
│        │                           │
│        ▼                           │
│     CPU 0  ← 单核处理(瓶颈)      │
│                                    │
│  问题:                             │
│  - 单核成为瓶颈                     │
│  - 其他CPU空闲                     │
│  - 最大吞吐量~10Gbps                │
└────────────────────────────────────┘

RSS多队列方案:
┌────────────────────────────────────────────────┐
│  网卡(支持RSS)                                │
│                                                │
│  数据包到达 → 五元组哈希                        │
│  (源IP, 目的IP, 源端口, 目的端口, 协议)        │
│           │                                    │
│           ▼                                    │
│  ┌─────────────────┐                          │
│  │  哈希函数        │                          │
│  │  (Toeplitz)     │                          │
│  └────────┬────────┘                          │
│           │                                    │
│           ├─────────┬─────────┬────────┬─────┐│
│           │         │         │        │     ││
│        Queue 0   Queue 1   Queue 2  Queue 3 ││
│           │         │         │        │     ││
│           ▼         ▼         ▼        ▼     ││
│        CPU 0     CPU 1     CPU 2    CPU 3    ││
│                                                │
│  优势:                                         │
│  - 并行处理(多核利用)                         │
│  - 同一流的包保序(同一队列)                   │
│  - 吞吐量提升N倍(N=队列数)                    │
└────────────────────────────────────────────────┘

RSS配置示例(Linux):
┌──────────────────────────────────────┐
│ # 查看网卡队列数                      │
│ ethtool -l eth0                      │
│                                      │
│ # 设置队列数为4                       │
│ ethtool -L eth0 combined 4           │
│                                      │
│ # 查看队列中断分布                    │
│ cat /proc/interrupts | grep eth0     │
│                                      │
│ # 绑定队列到特定CPU                   │
│ echo 1 > /proc/irq/125/smp_affinity  │
│ echo 2 > /proc/irq/126/smp_affinity  │
│ echo 4 > /proc/irq/127/smp_affinity  │
│ echo 8 > /proc/irq/128/smp_affinity  │
└──────────────────────────────────────┘

Toeplitz哈希算法:
┌──────────────────────────────────────┐
│ hash = 0                             │
│ for each byte in (源IP + 目的IP +    │
│                    源端口 + 目的端口):│
│   for each bit in byte:              │
│     if bit == 1:                     │
│       hash ^= key[current_bit]       │
│                                      │
│ queue = hash % num_queues            │
│                                      │
│ 特性:                                │
│ - 确定性(同一流总是同一队列)         │
│ - 均匀分布                            │
│ - 硬件加速                            │
└──────────────────────────────────────┘

2. 交换机与路由器

2.1 交换机工作原理

┌─────────────────────────────────────────────────────────────┐
│              以太网交换机架构                                 │
└─────────────────────────────────────────────────────────────┘

交换机内部结构:
┌───────────────────────────────────────────────────────────┐
│                        以太网交换机                        │
│                                                           │
│  ┌────┐  ┌────┐  ┌────┐  ┌────┐                         │
│  │端口1│  │端口2│  │端口3│  │端口N│  物理端口             │
│  └─┬──┘  └─┬──┘  └─┬──┘  └─┬──┘                         │
│    │       │       │       │                            │
│  ┌─▼───────▼───────▼───────▼──┐                         │
│  │    入口处理 (Ingress)       │                         │
│  │  - 解析以太网帧              │                         │
│  │  - VLAN处理                 │                         │
│  │  - ACL匹配                  │                         │
│  └────────────┬────────────────┘                         │
│               │                                          │
│  ┌────────────▼────────────────┐                         │
│  │    交换矩阵 (Switching Fabric)│                        │
│  │  ┌────────────────────────┐ │                         │
│  │  │  MAC地址表 (CAM/TCAM)  │ │                         │
│  │  │ ┌──────────┬─────────┐ │ │                         │
│  │  │ │ MAC地址  │ 端口号  │ │ │                         │
│  │  │ ├──────────┼─────────┤ │ │                         │
│  │  │ │AA:BB:CC:1│   1     │ │ │                         │
│  │  │ │AA:BB:CC:2│   2     │ │ │                         │
│  │  │ │AA:BB:CC:3│   3     │ │ │                         │
│  │  │ └──────────┴─────────┘ │ │                         │
│  │  └────────────────────────┘ │                         │
│  │                              │                         │
│  │  ┌────────────────────────┐ │                         │
│  │  │  VLAN表                 │ │                         │
│  │  │ ┌──────┬──────────────┐│ │                         │
│  │  │ │VLAN ID│   端口成员   ││ │                         │
│  │  │ ├──────┼──────────────┤│ │                         │
│  │  │ │  10  │ 1,2,3,4      ││ │                         │
│  │  │ │  20  │ 5,6,7,8      ││ │                         │
│  │  │ └──────┴──────────────┘│ │                         │
│  │  └────────────────────────┘ │                         │
│  └────────────┬────────────────┘                         │
│               │                                          │
│  ┌────────────▼────────────────┐                         │
│  │    出口处理 (Egress)         │                         │
│  │  - 队列调度                  │                         │
│  │  - 流量整形                  │                         │
│  │  - VLAN标签插入              │                         │
│  └────────────┬────────────────┘                         │
│               │                                          │
│          转发到目标端口                                   │
└───────────────────────────────────────────────────────────┘

帧转发流程:
┌──────────────────────────────────────────┐
│  1. 接收帧                                │
│     ┌──────────────────────────────┐    │
│     │ 目的MAC │ 源MAC │ 数据 │ CRC │    │
│     └──────────────────────────────┘    │
│     ↓                                    │
│  2. 查找MAC地址表                         │
│     目的MAC: AA:BB:CC:DD:EE:FF           │
│     ↓                                    │
│  3. 决策                                 │
│     ├─ 已知单播 → 转发到特定端口          │
│     ├─ 未知单播 → 泛洪到所有端口(除源)    │
│     ├─ 广播     → 泛洪到所有端口          │
│     └─ 组播     → 转发到组播组成员        │
│     ↓                                    │
│  4. 学习源MAC地址                         │
│     源MAC + 入端口 → 更新MAC表            │
│     ↓                                    │
│  5. 转发帧                                │
└──────────────────────────────────────────┘

性能指标:
┌──────────────────────────────────────┐
│  转发速率(包/秒):                   │
│    1G端口:1.488 Mpps (线速)         │
│    10G端口:14.88 Mpps               │
│    100G端口:148.8 Mpps              │
│                                      │
│  计算公式:                           │
│    线速pps = 带宽 / (帧大小×8)        │
│                                      │
│  64字节小包(最坏情况):              │
│    = 1Gbps / (64+20)字节×8           │
│    = 1.488 Mpps                      │
│                                      │
│  交换容量(背板带宽):                │
│    48×1G + 4×10G = 88 Gbps          │
│    全双工:88 × 2 = 176 Gbps         │
└──────────────────────────────────────┘

2.2 三层交换与路由

┌─────────────────────────────────────────────────────────────┐
│              三层交换机 vs 路由器                             │
└─────────────────────────────────────────────────────────────┘

二层交换 vs 三层交换:
┌────────────────────────────────────┐
│  二层交换(MAC地址)                │
│  ┌──────────────────────────────┐ │
│  │  VLAN 10: 192.168.1.0/24     │ │
│  │  ┌──┐  ┌──┐  ┌──┐           │ │
│  │  │PC│  │PC│  │PC│           │ │
│  │  └──┘  └──┘  └──┘           │ │
│  └──────────────────────────────┘ │
│           │ (不能直接通信)         │
│  ┌────────▼──────────────────┐   │
│  │  VLAN 20: 192.168.2.0/24  │   │
│  │  ┌──┐  ┌──┐               │   │
│  │  │PC│  │PC│               │   │
│  │  └──┘  └──┘               │   │
│  └───────────────────────────┘   │
└────────────────────────────────────┘

┌────────────────────────────────────┐
│  三层交换(IP路由)                 │
│  ┌──────────────────────────────┐ │
│  │  VLAN 10                     │ │
│  │  SVI: 192.168.1.1/24         │ │
│  │  ┌──┐  ┌──┐  ┌──┐           │ │
│  │  │PC│  │PC│  │PC│           │ │
│  │  └──┘  └──┘  └──┘           │ │
│  └──────────┬───────────────────┘ │
│             │ (三层路由)           │
│  ┌──────────▼───────────────────┐ │
│  │  VLAN 20                     │ │
│  │  SVI: 192.168.2.1/24         │ │
│  │  ┌──┐  ┌──┐                 │ │
│  │  │PC│  │PC│                 │ │
│  │  └──┘  └──┘                 │ │
│  └──────────────────────────────┘ │
│                                    │
│  路由表:                           │
│  192.168.1.0/24 → VLAN 10         │
│  192.168.2.0/24 → VLAN 20         │
└────────────────────────────────────┘

路由查找(最长前缀匹配):
┌──────────────────────────────────────┐
│  目的IP: 192.168.1.100               │
│                                      │
│  路由表:                             │
│  0.0.0.0/0          → 默认网关       │
│  192.168.0.0/16     → 内网路由       │
│  192.168.1.0/24     → VLAN 10 ✓     │
│  192.168.1.128/25   → 子网           │
│                                      │
│  匹配最长前缀:/24                    │
│  → 转发到VLAN 10                     │
└──────────────────────────────────────┘

TCAM硬件加速(三态内容寻址存储器):
┌──────────────────────────────────────┐
│  传统软件路由:O(log n)查找           │
│  TCAM硬件:O(1)并行查找               │
│                                      │
│  TCAM条目格式(三态:0/1/X):         │
│  ┌────────────┬──────┬────────┐     │
│  │  IP前缀    │ 掩码 │ 下一跳  │     │
│  ├────────────┼──────┼────────┤     │
│  │192.168.1.0 │  /24 │ Port 1 │     │
│  │192.168.2.0 │  /24 │ Port 2 │     │
│  │10.0.0.0    │  /8  │ Port 3 │     │
│  └────────────┴──────┴────────┘     │
│                                      │
│  查找时间:单周期(~5ns)              │
│  吞吐量:线速转发                     │
└──────────────────────────────────────┘

3. RDMA技术

3.1 RDMA vs TCP对比

┌─────────────────────────────────────────────────────────────┐
│              RDMA vs 传统TCP/IP                               │
└─────────────────────────────────────────────────────────────┘

传统TCP/IP数据传输:
┌────────────────────────────────────────────────┐
│  应用程序                                       │
│  ┌──────────────────────────────────────────┐ │
│  │ send(socket, buffer, len)                │ │
│  └────────────┬─────────────────────────────┘ │
│               │ 用户态                         │
│  ═════════════╪═════════════════════════════  │
│               │ 内核态                         │
│  ┌────────────▼─────────────────────────────┐ │
│  │  1. 系统调用(上下文切换)                │ │
│  └────────────┬─────────────────────────────┘ │
│  ┌────────────▼─────────────────────────────┐ │
│  │  2. 拷贝到内核缓冲区(第1次拷贝)         │ │
│  └────────────┬─────────────────────────────┘ │
│  ┌────────────▼─────────────────────────────┐ │
│  │  3. TCP/IP协议栈处理                     │ │
│  │     - TCP分段                             │ │
│  │     - IP路由                              │ │
│  │     - Checksum计算                        │ │
│  └────────────┬─────────────────────────────┘ │
│  ┌────────────▼─────────────────────────────┐ │
│  │  4. 拷贝到网卡缓冲区(第2次拷贝)         │ │
│  └────────────┬─────────────────────────────┘ │
│  ┌────────────▼─────────────────────────────┐ │
│  │  5. DMA到网卡发送                         │ │
│  └────────────┬─────────────────────────────┘ │
│               ▼                                │
│            网络传输                            │
│                                                │
│  问题:                                         │
│  - 2次数据拷贝(CPU开销大)                     │
│  - 多次上下文切换                               │
│  - CPU处理协议栈                               │
│  - 延迟高(~10-100μs)                         │
└────────────────────────────────────────────────┘

RDMA数据传输(零拷贝):
┌────────────────────────────────────────────────┐
│  应用程序                                       │
│  ┌──────────────────────────────────────────┐ │
│  │ ibv_post_send(qp, wr)                    │ │
│  │ (仅下发工作请求,不拷贝数据)              │ │
│  └────────────┬─────────────────────────────┘ │
│               │                                │
│  ┌────────────▼─────────────────────────────┐ │
│  │  RDMA网卡 (RNIC)                          │ │
│  │  ┌────────────────────────────────────┐  │ │
│  │  │ 1. 直接读取用户态缓冲区(DMA)      │  │ │
│  │  └────────────────────────────────────┘  │ │
│  │  ┌────────────────────────────────────┐  │ │
│  │  │ 2. 硬件处理协议(无CPU参与)        │  │ │
│  │  │    - RDMA协议封装                   │  │ │
│  │  │    - CRC计算                        │  │ │
│  │  └────────────────────────────────────┘  │ │
│  │  ┌────────────────────────────────────┐  │ │
│  │  │ 3. 直接发送                         │  │ │
│  │  └────────────────────────────────────┘  │ │
│  └──────────────┬───────────────────────────┘ │
│                 ▼                              │
│              网络传输                          │
│                                                │
│  优势:                                         │
│  - 零拷贝(CPU不参与)                          │
│  - 零CPU开销(协议卸载到网卡)                  │
│  - 内核旁路(用户态直接访问硬件)                │
│  - 低延迟(~1-2μs)                            │
└────────────────────────────────────────────────┘

性能对比:
┌──────────────┬────────────┬────────────┐
│  指标        │  TCP/IP    │   RDMA     │
├──────────────┼────────────┼────────────┤
│ 延迟         │  10-100μs  │  1-2μs     │
│ CPU占用      │  50-80%    │  <5%       │
│ 带宽         │  ~9Gbps    │  ~100Gbps  │
│              │  (10GbE)   │  (100GbE)  │
│ 数据拷贝     │  2次       │  0次       │
│ 上下文切换   │  多次      │  极少      │
└──────────────┴────────────┴────────────┘

3.2 RDMA协议类型

┌─────────────────────────────────────────────────────────────┐
│              RDMA协议栈对比                                   │
└─────────────────────────────────────────────────────────────┘

1. InfiniBand(原生RDMA)
┌──────────────────────────────────────┐
│  应用程序                             │
│       │                              │
│  ┌────▼────────────┐                 │
│  │  Verbs API      │  编程接口       │
│  └────┬────────────┘                 │
│       │                              │
│  ┌────▼────────────┐                 │
│  │  IB Transport   │  传输层         │
│  │  (RC/UC/UD)     │                 │
│  └────┬────────────┘                 │
│       │                              │
│  ┌────▼────────────┐                 │
│  │  IB Network     │  网络层         │
│  └────┬────────────┘                 │
│       │                              │
│  ┌────▼────────────┐                 │
│  │  IB Link        │  链路层         │
│  └────┬────────────┘                 │
│       │                              │
│  ┌────▼────────────┐                 │
│  │  IB Physical    │  物理层         │
│  └─────────────────┘                 │
│                                      │
│  专用网络,性能最优                   │
│  成本高,不兼容以太网                 │
└──────────────────────────────────────┘

2. RoCE (RDMA over Converged Ethernet)
┌──────────────────────────────────────┐
│  应用程序                             │
│       │                              │
│  ┌────▼────────────┐                 │
│  │  Verbs API      │  同InfiniBand   │
│  └────┬────────────┘                 │
│       │                              │
│  ┌────▼────────────┐                 │
│  │  IB Transport   │                 │
│  └────┬────────────┘                 │
│       │                              │
│  ┌────▼────────────┐                 │
│  │  Ethernet/IP    │  复用以太网     │
│  │  (RoCEv2使用UDP)│                 │
│  └────┬────────────┘                 │
│       │                              │
│  ┌────▼────────────┐                 │
│  │  Ethernet       │  标准以太网     │
│  └─────────────────┘                 │
│                                      │
│  兼容现有网络,性价比高                │
│  需要无损网络(PFC/ECN)              │
└──────────────────────────────────────┘

3. iWARP (Internet Wide Area RDMA Protocol)
┌──────────────────────────────────────┐
│  应用程序                             │
│       │                              │
│  ┌────▼────────────┐                 │
│  │  Verbs API      │                 │
│  └────┬────────────┘                 │
│       │                              │
│  ┌────▼────────────┐                 │
│  │  iWARP          │  RDMA层         │
│  └────┬────────────┘                 │
│       │                              │
│  ┌────▼────────────┐                 │
│  │  MPA/DDP        │  消息层         │
│  └────┬────────────┘                 │
│       │                              │
│  ┌────▼────────────┐                 │
│  │  TCP/SCTP       │  传输层         │
│  └────┬────────────┘                 │
│       │                              │
│  ┌────▼────────────┐                 │
│  │  IP/Ethernet    │  标准协议栈     │
│  └─────────────────┘                 │
│                                      │
│  兼容性最好,可跨互联网                │
│  性能略低(TCP开销)                  │
└──────────────────────────────────────┘

RDMA操作类型:
┌──────────────────────────────────────┐
│  1. SEND/RECV                        │
│     双端操作(类似传统send/recv)     │
│                                      │
│  2. WRITE                            │
│     单端操作(直接写远端内存)         │
│     远端无感知,零CPU开销             │
│                                      │
│  3. READ                             │
│     单端操作(直接读远端内存)         │
│                                      │
│  4. ATOMIC                           │
│     原子操作(Compare-and-Swap等)    │
└──────────────────────────────────────┘

4. 网络卸载技术

4.1 TSO/LRO/GRO

┌─────────────────────────────────────────────────────────────┐
│              网络卸载技术(Offload Engines)                  │
└─────────────────────────────────────────────────────────────┘

TSO (TCP Segmentation Offload) - 发送端:
┌────────────────────────────────────────┐
│  无TSO(CPU负担重):                    │
│                                        │
│  应用程序:64KB数据                     │
│       │                                │
│       ▼                                │
│  TCP/IP栈:分段为45个1448字节包         │
│       │   (CPU处理45次)                │
│       │                                │
│  ┌────▼────┐                           │
│  │  Packet │ 1448B                     │
│  ├─────────┤                           │
│  │  Packet │ 1448B                     │
│  ├─────────┤                           │
│  │   ...   │ × 45                      │
│  └─────────┘                           │
│       │                                │
│       ▼                                │
│     网卡                                │
└────────────────────────────────────────┘

┌────────────────────────────────────────┐
│  启用TSO(网卡分段):                   │
│                                        │
│  应用程序:64KB数据                     │
│       │                                │
│       ▼                                │
│  TCP/IP栈:创建单个超大段               │
│       │   (CPU处理1次)                 │
│       │                                │
│  ┌────▼────────┐                       │
│  │  Super Seg  │  64KB                 │
│  └─────────────┘                       │
│       │                                │
│       ▼                                │
│     网卡:硬件分段为45个包              │
│  ┌─────────┐                           │
│  │  Packet │ ← 自动添加TCP/IP头         │
│  ├─────────┤                           │
│  │  Packet │                           │
│  ├─────────┤                           │
│  │   ...   │ × 45                      │
│  └─────────┘                           │
│                                        │
│  CPU节省:(45-1)/45 = 97.8%            │
└────────────────────────────────────────┘

LRO/GRO (Large/Generic Receive Offload) - 接收端:
┌────────────────────────────────────────┐
│  无GRO:                                 │
│                                        │
│  网卡接收45个1448字节包                 │
│       │                                │
│       ▼                                │
│  每个包触发一次中断+协议栈处理           │
│  ┌─────────┐                           │
│  │  Packet │ → 中断 → TCP栈            │
│  ├─────────┤                           │
│  │  Packet │ → 中断 → TCP栈            │
│  ├─────────┤                           │
│  │   ...   │ × 45次处理                │
│  └─────────┘                           │
│       │                                │
│       ▼                                │
│  应用程序:recv() 45次                  │
└────────────────────────────────────────┘

┌────────────────────────────────────────┐
│  启用GRO:                               │
│                                        │
│  网卡/驱动聚合同一流的包                 │
│  ┌─────────┐                           │
│  │  Packet │                           │
│  ├─────────┤                           │
│  │  Packet │  → 聚合                   │
│  ├─────────┤     ↓                     │
│  │   ...   │  ┌──────────┐            │
│  └─────────┘  │ 64KB聚合包│            │
│               └──────┬────┘            │
│                      │                 │
│                      ▼                 │
│               单次中断+协议栈处理        │
│                      │                 │
│                      ▼                 │
│               应用程序:recv() 1次      │
│                                        │
│  CPU节省:类似TSO,~98%                 │
└────────────────────────────────────────┘

其他卸载技术:
┌──────────────────────────────────────┐
│  Checksum Offload                    │
│  - TX: 网卡计算TCP/UDP/IP校验和       │
│  - RX: 网卡验证校验和                 │
│                                      │
│  VLAN Offload                        │
│  - TX: 网卡插入VLAN标签               │
│  - RX: 网卡剥离VLAN标签               │
│                                      │
│  RSS (Receive Side Scaling)          │
│  - 多队列哈希分发                     │
│                                      │
│  IPsec Offload                       │
│  - 加密/解密卸载到网卡                │
└──────────────────────────────────────┘

5. SmartNIC与DPU

5.1 SmartNIC架构

┌─────────────────────────────────────────────────────────────┐
│              SmartNIC架构(可编程网卡)                       │
└─────────────────────────────────────────────────────────────┘

传统网卡 vs SmartNIC:
┌────────────────────────────────────────┐
│  传统网卡(固定功能):                  │
│  ┌──────────────────────────────────┐ │
│  │  PCIe ← → MAC/PHY                │ │
│  │  固定硬件逻辑(不可编程)          │ │
│  └──────────────────────────────────┘ │
└────────────────────────────────────────┘

┌────────────────────────────────────────────────────────────┐
│  SmartNIC(可编程):                                        │
│  ┌────────────────────────────────────────────────────────┐│
│  │  主机接口 (PCIe Gen4 x16)                              ││
│  └──────────────┬─────────────────────────────────────────┘│
│                 │                                          │
│  ┌──────────────▼─────────────────────────────────────────┐│
│  │  可编程核心                                             ││
│  │  ┌──────────────────────────────────────────────────┐ ││
│  │  │  多核CPU (ARM Cortex-A72 × 16)                   │ ││
│  │  │  - 运行Linux                                     │ ││
│  │  │  - 网络功能处理                                   │ ││
│  │  └──────────────────────────────────────────────────┘ ││
│  │                                                        ││
│  │  ┌──────────────────────────────────────────────────┐ ││
│  │  │  硬件加速器                                       │ ││
│  │  │  - 数据包处理流水线                               │ ││
│  │  │  - 加密/解密引擎                                  │ ││
│  │  │  - 压缩/解压引擎                                  │ ││
│  │  │  - 正则表达式匹配                                 │ ││
│  │  └──────────────────────────────────────────────────┘ ││
│  │                                                        ││
│  │  ┌──────────────────────────────────────────────────┐ ││
│  │  │  FPGA (可选)                                      │ ││
│  │  │  - 用户自定义逻辑                                 │ ││
│  │  │  - P4可编程                                       │ ││
│  │  └──────────────────────────────────────────────────┘ ││
│  │                                                        ││
│  │  ┌──────────────────────────────────────────────────┐ ││
│  │  │  内存 (DDR4 16GB)                                │ ││
│  │  └──────────────────────────────────────────────────┘ ││
│  └────────────────┬───────────────────────────────────────┘│
│                   │                                        │
│  ┌────────────────▼───────────────────────────────────────┐│
│  │  网络接口 (2×100GbE / 2×200GbE)                        ││
│  └────────────────────────────────────────────────────────┘│
└────────────────────────────────────────────────────────────┘

应用场景:
┌──────────────────────────────────────┐
│  1. OVS/eBPF加速                     │
│     软件定义网络卸载                  │
│                                      │
│  2. 负载均衡                          │
│     L4/L7流量分发                    │
│                                      │
│  3. 防火墙/IDS                        │
│     安全策略硬件加速                  │
│                                      │
│  4. 加密加速                          │
│     IPsec/TLS卸载                   │
│                                      │
│  5. 存储加速                          │
│     NVMe-oF target卸载               │
│                                      │
│  6. 虚拟化                            │
│     SR-IOV++, VirtIO卸载            │
└──────────────────────────────────────┘

DPU (Data Processing Unit) 趋势:
SmartNIC + AI加速器 + 存储控制器
= 完整的基础设施处理器

6. 网络性能测试

6.1 网络性能测试工具

bash
#!/bin/bash
# 网络性能测试脚本集合

echo "========== 网卡信息查询 =========="
# 网卡基本信息
ip link show
ethtool eth0

# 网卡驱动和固件版本
ethtool -i eth0

# 网卡统计信息
ethtool -S eth0 | head -20

echo -e "\n========== 网卡性能参数 =========="
# 队列配置
ethtool -l eth0

# Ring buffer大小
ethtool -g eth0

# 卸载功能状态
ethtool -k eth0 | grep -E "tcp-segmentation|receive-offload|checksum"

# 中断合并(减少中断频率)
ethtool -c eth0

echo -e "\n========== iperf3带宽测试 =========="
# 服务端:iperf3 -s
# 客户端测试TCP带宽
iperf3 -c 192.168.1.100 -t 30 -P 4

# UDP测试(指定带宽)
iperf3 -c 192.168.1.100 -u -b 10G -t 30

echo -e "\n========== qperf延迟测试 =========="
# 测试TCP延迟
qperf 192.168.1.100 tcp_lat

# 测试带宽
qperf 192.168.1.100 tcp_bw

# RDMA测试(如果支持)
qperf 192.168.1.100 rc_lat rc_bw

echo -e "\n========== 网络丢包检查 =========="
# 查看接口错误统计
netstat -i

# 详细错误计数
ip -s link show eth0

# 查看系统丢包
cat /proc/net/softnet_stat

echo -e "\n========== 网卡中断统计 =========="
# 查看网卡中断分布
cat /proc/interrupts | grep eth0

# 实时监控中断速率
watch -n 1 'cat /proc/interrupts | grep eth0'

6.2 Python性能测试脚本

python
#!/usr/bin/env python3
"""
网络性能测试脚本
"""

import socket
import time
import subprocess
import struct

def test_tcp_latency(host, port=5001, count=10000):
    """测试TCP延迟(ping-pong模式)"""
    print(f"=== TCP延迟测试 ({count}次ping-pong) ===")

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((host, port))

    msg = b'X' * 64  # 64字节消息
    latencies = []

    # 预热
    for _ in range(100):
        sock.sendall(msg)
        sock.recv(64)

    # 测试
    for _ in range(count):
        start = time.perf_counter()
        sock.sendall(msg)
        sock.recv(64)
        end = time.perf_counter()

        latency = (end - start) * 1e6  # 微秒
        latencies.append(latency)

    sock.close()

    # 统计
    import statistics
    avg_lat = statistics.mean(latencies)
    min_lat = min(latencies)
    max_lat = max(latencies)
    p50_lat = statistics.median(latencies)
    p99_lat = sorted(latencies)[int(count * 0.99)]

    print(f"平均延迟: {avg_lat:.2f} μs")
    print(f"最小延迟: {min_lat:.2f} μs")
    print(f"最大延迟: {max_lat:.2f} μs")
    print(f"P50延迟: {p50_lat:.2f} μs")
    print(f"P99延迟: {p99_lat:.2f} μs")

def test_tcp_bandwidth(host, port=5001, duration=10):
    """测试TCP带宽"""
    print(f"\n=== TCP带宽测试 ({duration}秒) ===")

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((host, port))

    msg = b'X' * 65536  # 64KB块
    total_bytes = 0

    start = time.perf_counter()
    end_time = start + duration

    while time.perf_counter() < end_time:
        sock.sendall(msg)
        total_bytes += len(msg)

    elapsed = time.perf_counter() - start
    sock.close()

    bandwidth_gbps = (total_bytes * 8) / elapsed / 1e9
    print(f"发送带宽: {bandwidth_gbps:.2f} Gbps")
    print(f"发送数据: {total_bytes / 1e9:.2f} GB")

def test_udp_pps(host, port=5001, pps=100000, duration=10):
    """测试UDP包速率"""
    print(f"\n=== UDP PPS测试 (目标{pps} pps) ===")

    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    msg = b'X' * 64  # 小包

    interval = 1.0 / pps
    total_packets = 0

    start = time.perf_counter()
    end_time = start + duration
    next_send = start

    while time.perf_counter() < end_time:
        now = time.perf_counter()
        if now >= next_send:
            sock.sendto(msg, (host, port))
            total_packets += 1
            next_send += interval

    elapsed = time.perf_counter() - start
    sock.close()

    actual_pps = total_packets / elapsed
    print(f"发送速率: {actual_pps:.0f} pps")
    print(f"总包数: {total_packets}")

def check_nic_stats(interface='eth0'):
    """检查网卡统计信息"""
    print(f"\n=== {interface} 统计信息 ===")

    try:
        # 使用ethtool获取统计
        result = subprocess.run(
            ['ethtool', '-S', interface],
            capture_output=True,
            text=True
        )

        # 显示关键指标
        for line in result.stdout.split('\n'):
            if any(keyword in line for keyword in
                  ['rx_packets', 'tx_packets', 'rx_bytes',
                   'tx_bytes', 'rx_errors', 'tx_errors',
                   'rx_dropped', 'tx_dropped']):
                print(f"  {line.strip()}")

    except FileNotFoundError:
        print("需要安装ethtool")

    # 查看/proc/net/dev
    try:
        with open(f'/sys/class/net/{interface}/statistics/rx_bytes') as f:
            rx_bytes = int(f.read())
        with open(f'/sys/class/net/{interface}/statistics/tx_bytes') as f:
            tx_bytes = int(f.read())
        with open(f'/sys/class/net/{interface}/statistics/rx_packets') as f:
            rx_packets = int(f.read())
        with open(f'/sys/class/net/{interface}/statistics/tx_packets') as f:
            tx_packets = int(f.read())

        print(f"\n接收: {rx_bytes/1e9:.2f} GB, {rx_packets} 包")
        print(f"发送: {tx_bytes/1e9:.2f} GB, {tx_packets} 包")

    except:
        pass

def main():
    """主函数"""
    print("网络性能测试")
    print("=" * 60)

    # 配置
    server_host = '192.168.1.100'

    # 延迟测试(需要对端运行echo服务器)
    # test_tcp_latency(server_host)

    # 带宽测试(需要对端运行iperf3 -s)
    # test_tcp_bandwidth(server_host)

    # PPS测试
    # test_udp_pps(server_host)

    # 网卡统计
    check_nic_stats('eth0')

    print("\n" + "=" * 60)

if __name__ == "__main__":
    main()

7. 学习资源与总结

7.1 关键要点总结

┌─────────────────────────────────────────────────────────────┐
│                  网络硬件核心概念                             │
└─────────────────────────────────────────────────────────────┘

1. 网卡架构
   ├─ PHY → MAC → 控制器 → PCIe
   ├─ 多队列(RSS):并行处理
   ├─ DMA引擎:零拷贝传输
   └─ MSI-X:中断亲和性

2. 交换机
   ├─ MAC地址表:硬件转发
   ├─ VLAN:二层隔离
   ├─ 三层交换:TCAM加速路由
   └─ 无损网络:PFC/ECN

3. RDMA技术
   ├─ 零拷贝:直接访问内存
   ├─ 内核旁路:用户态通信
   ├─ 协议:IB/RoCE/iWARP
   └─ 延迟:<2μs

4. 网络卸载
   ├─ TSO/LRO:分段卸载
   ├─ Checksum:校验卸载
   ├─ RSS:多队列分发
   └─ IPsec:加密卸载

5. SmartNIC/DPU
   ├─ 可编程:CPU+FPGA+加速器
   ├─ 应用:OVS/防火墙/加密
   ├─ 趋势:基础设施卸载
   └─ 性能:接近线速

6. 性能优化
   ├─ 中断合并:减少中断
   ├─ Ring buffer:增大缓冲
   ├─ CPU亲和性:绑定核心
   ├─ 巨型帧:减少开销
   └─ NUMA:本地化网卡
└─────────────────────────────────────────────────────────────┘

下一步:学习电源与散热管理,理解功耗优化和冷却方案。

文件大小:约30KB 最后更新:2024年

💬 讨论

使用 GitHub 账号登录后即可参与讨论

基于 MIT 许可发布