半小时玩转RDMA:从零跑通高速网络通信

一、 一句话说清 RDMA

|--------|------------------------------------|--------------------------|
| | 传统网络 | RDMA |
| 数据路径 | App → 内核 → 网卡 → 网络 → 网卡 → 内核 → App | App → 网卡 → 网络 → 网卡 → App |
| CPU 参与 | 每次拷贝都打断 CPU | 零拷贝 + CPU 旁路 |
| 延迟 | 10--50 μs | 1--3 μs​ |
| CPU 占用 | ~70% | **<10%**​ |

一句话: RDMA 让网卡直接读你的内存,不经过操作系统。


  • RDMA工作原理是怎么样的?

红色路径为传统TCP/IP数据传输路径,发送端APP需将待传输数据写入OS的buffer,然后经过CPU拷贝到网卡的buffer,网卡将数据处理成报文,经过中间网络发送到接收端。接收端网卡收到报文数据后,先缓存到buffer中,然后OS从网卡buffer取数据到OS的缓存,最后才是接收端APP从OS的缓存中获取数据。可以看到整个过程需要CPU强参与,并且数据经过多次拷贝。

那么RDMA数据拷贝无需CPU参与,发送端具备RDMA协议栈的HCA网卡直接从APP中获取待传输数据,封装成报文通过中间网络发送到接收端,接收端HCA直接将数据传递给APP,避免了多次数据拷贝,有效提升性能。

三、 为什么 AI 训练离不开它

  • NVIDIA DGX、华为 Atlas 900、Google TPU Pod------万卡互联全用 RDMA
  • AllReduce 一次梯度同步要传几 GB,TCP 扛不住(慢启动 + 队头阻塞)
  • 存储侧:NVMe over Fabrics 也是 RDMA
  • 云厂商:阿里神龙、AWS EFA、华为云弹性网络

所以:搞懂 RDMA = 搞懂 AI 基础设施的底层语言。


四、 实验环境

|------------|----------------------------------------------|
| 项目 | 要求 |
| 宿主机 | Windows |
| 虚拟化 | VMware |
| 虚拟机 | 2 台 Ubuntu 22.04 Server(2 vCPU / 2GB RAM 就够) |
| 网络 | 两台 VM 网卡设为"内部网络"(Internal Network) |
| RDMA 软件 | rdma-core、perftest、iproute2 |

网络规划:

|------------|-------------|----------------|
| 节点 | 主机名 | IP |
| Node-A | rdma-srv | 192.168.95.128 |
| Node-B | rdma-cli | 192.168.95.130 |


五、 环境搭建

两台 VM 都执行:

1. 配静态 IP

2. 验证互通

ping 192.168.95.130 # 从 Node-A 执行

3. 安装 RDMA 工具链sudo apt updatesudo apt install -y rdma-core ibverbs-utils perftest iproute2 \

libibverbs-dev librdmacm-dev

4. 加载 Soft-RoCE 模块sudo modprobe rdma_rxe

5. 创建 RXE 设备,绑定到你的网卡(通常是 enp0s3)sudo rdma link add rxe_0 type rxe netdev enp0s3

6. 验证

rdma link show# 应看到:rxe_0/1 state ACTIVE physical_state LINK_UP

⚠️ 踩坑预警:

  • rdma link add 报错 File exists → 说明已创建过,先 rdma link del rxe_0 再试
  • state DOWN → 检查网卡名对不对,ip link show 确认
  • Ubuntu 24.04 内核自带 rdma_rxe,22.04 需 apt install linux-modules-extra-$(uname -r)

六、 跑第一个 RDMA 测试

先开服务端(Node-A):

ib_send_bw -d rxe_0 -x 2 --report_gbits

再开客户端(Node-B):

ib_send_bw -d rxe_0 -x 2 --report_gbits 192.168.95.128

预期输出:

看到数字就对了!哪怕只有 0.57 Gbps(≈71 MB/s),你跑通的也是真正的 RDMA 协议栈。


七、 为什么只有 71 MB/s?

|------------|------------------------------------|
| 原因 | 解释 |
| 虚拟机 CPU 瓶颈 | Soft-RoCE 用 CPU 模拟网卡,不是真硬件 offload |
| 单 QP | 默认只开 1 个 Queue Pair,真机开 8--32 个并行 |
| MTU 1500 | 默认小包,真机用 4200/9000 |
| 内部网络带宽 | VirtualBox 内部网络走宿主机内存,不是真网卡 |

真机对比 :NVIDIA ConnectX-6 + 100GbE 交换机 → 100 Gbps 轻松跑满。

所以:这篇的价值不是性能,是让你看懂协议长什么样。


八、 抓包看透 RoCEv2(Wireshark 逐字段)

新终端抓包(Node-A):

sudo tcpdump -i enp0s3 -w rdma.pcap udp port 4791

另开终端重跑ib_send_bw,几秒后 Ctrl+C。

Wireshark 打开 rdma.pcap**,过滤**udp.port == 4791。

你会看到三类包滚动:

|----------------|----------------|----------------|
| 类型 | Opcode | 含义 |
| RC Send First | 0 | 大消息的第一个分片 |
| RC Send Middle | 1 | 中间分片(只有 PSN 变) |
| RC Send Last | 2 | 最后一个分片(要求 ACK) |
| RC ACK | 17 | 接收端确认 |

点开第一个包,展开 InfiniBand**→** BTH**(Base Transport Header)**:

|------------|----------------|------------------|
| 字段 | 值 | 什么意思 |
| Opcode | 0 (Send First) | 这是 64KB 消息的第 1 段 |
| PSN | 858106 | 包序列号,每包 +1 |
| Dest QP | 0x0011 | 对端队列对编号 |
| Dest Port | 4791 | RoCEv2 固定 UDP 端口 |

1、 RC Send First 报文解析

双击第一个数据包,展开 BTH 头部:

• Opcode = 0 (SEND First) → 大消息的第一个分片

• PSN = 858106 → 包序列号,每个包递增1

• Dest QP = 0x0011 → 对端队列对编号

• Dest Port = 4791 → RoCEv2 固定端口

64KB消息 → MTU 1024 → 拆成64个包:First + 62×Middle + Last

2、 RC Send Middle 和 Last

连续滚动,你会看到:

• 一堆 RC Send Middle(仅PSN变化)

• 最后一个包:RC Send Last

展开 Last 包的 BTH:

✅ Acknowledge Request = 1(要求接收端回复ACK)

累积确认:收完一整条消息才回一个ACK,节省带宽

3、 RC Acknowledge 报文

找到 ACK 报文(Opcode = 17):

• PSN = 858169(等于发送端Last包的PSN)

• 含义:"截止到此PSN,我都收到了"

展开 AETH 扩展头:

• Syndrome = 31(正常ACK)

• Credit Count = 31(我还有31个缓冲槽,继续发)


九、 64KB 怎么拆成 64 个包

64 KB 消息 ÷ MTU 1024 B = 64 个 RDMA 报文

First\] → \[Middle\] × 62 → \[Last (AckReq=1)

↓

ACK ← 接收端

  • First 包:Opcode=0,带 BTH 头
  • Middle 包:Opcode=1,只变 PSN
  • Last 包:Opcode=2,AckReq=1(要求确认)
  • ACK 包:Opcode=17,PSN=858169(等于 Last 的 PSN),Syndrome=31(正常)

一次 64KB 消息 = 64 个数据包 + 1 个 ACK。服务端 CPU 只在最后 poll CQ,中间全由网卡硬件完成。


十、 整个交互流程图

客户端 服务端

| |

|---First------------------------->|

|---Middle × 62 ------------------>|

|---Last (AckReq=1)-------------->|

| | (网卡收完,写内存,

| | CPU 最后 poll CQ)

|<--ACK: PSN=858169, Credit=31----|

这就是 RDMA 的精髓:中间过程 CPU 完全不介入。


十一、 下一步

你已经做到的事:

  • ✅ 在一台笔记本上跑通 RDMA
  • ✅ 用 Soft-RoCE 模拟真实 RDMA 网卡
  • ✅ 抓包看懂 RoCEv2 报文结构
  • ✅ 理解 QP / PSN / BTH / ACK 机制

下一步可以学:

  • PFC(Priority Flow Control):为什么 AI 交换机要"按优先级暂停"
  • ECN + DCQCN:拥塞控制怎么在交换机+网卡之间闭环
  • NCCL + AllReduce:GPU 梯度同步怎么用 RDMA
  • 真机环境:ConnectX-5/6 + 博通交换机
相关推荐
砺星Leetx10 小时前
工业总线选型与对接实战:PROFINET、EtherCAT、EtherNet/IP、PROFIBUS、Modbus-TCP 与 CC-Link
网络·网络协议·tcp/ip·控制器·国产拧紧系统
流浪00118 小时前
计算机网络篇8:传输层——序列化与反序列化,TCP 面向字节流的报文边界由应用层自己切
网络协议·tcp/ip·计算机网络·1024程序员节·序列化反序列化·面向字节流·面向数据包
幻智星科技19 小时前
多通道数据采集中collect_end信号的妙用
网络协议·架构·udp·硬件架构
lazy H21 小时前
【计算机网络】第 5 篇:TCP 和 UDP 有什么区别?从 Java 后端场景理解两种传输协议
经验分享·后端·网络协议·tcp/ip·计算机网络·1024程序员节
gwf2161 天前
RC/UC/UD/XRC四种传输模式性能对比与实战选型
性能测试·rdma·芯片测试·dpu·roce·智能网卡·perftest
byte轻骑兵1 天前
【LMP】规范精讲[8]: 主从易位——角色切换的时序反转与微微网重构
网络协议·安全·蓝牙协议·lmp·链接管理
Sirens.1 天前
网络通信基础:IP、端口、协议分层与数据封装
java·网络·网络协议·tcp/ip·java-ee·1024程序员节
qq_429432301 天前
叫班系统对接 IP-PBX/SIP 与排班系统:接口方式与部署选型要点
网络·网络协议·tcp/ip·信息与通信·ip·1024程序员节·voip通信协议
智慧光迅AINOPOL1 天前
园区全光网IP+POL架构怎么设计:组网拓扑与带宽演进
网络协议·tcp/ip·架构