RDMA vs 传统以太网:寻址粒度为何决定性能天花板

在分布式存储、高性能计算(HPC)领域,我们经常听到 RDMA(Remote Direct Memory Access)能够显著降低延迟、提升吞吐。但很多人只知道 RDMA "快",却很少深入思考:为什么 RDMA 能够实现 CPU 零拷贝、零中断?答案藏在网络寻址的最小粒度里。

今天我们从一个看似简单却极易被忽视的问题切入:

"以太网只管到主机,而 RDMA 能精确到网口 ------ 这背后的技术原理是什么?"


一、传统以太网(TCP/IP):粗粒度的 "主机级" 寻址

1.1 传统以太网的寻址层次

在经典 TCP/IP 协议栈中,网络寻址是一个分层的概念:

复制代码
应用层(端口号,如 80、443)
    ↓  标识进程
传输层(TCP/UDP)
    ↓  复用/分用
网络层(IP 地址)
    ↓  标识主机
数据链路层(MAC 地址)
    ↓  标识网卡
物理层(物理链路)

表面上看起来,MAC 地址已经可以定位到网卡硬件,但实际网络操作中,这种定位能力是有限的。

1.2 IP 地址的现实:只负责 "找到主机"

场景一:多网口共用一个 IP(链路聚合 / 绑定)

企业级服务器通常会配置多个物理网口,通过 网卡绑定链路聚合(LACP) 实现带宽叠加和高可用。在这种场景下:

复制代码
服务器 A 配置:
  - 物理网口 eth0(MAC: aa:bb:cc:11:22:33)
  - 物理网口 eth1(MAC: aa:bb:cc:44:55:66)
  - 绑定接口 bond0(IP: 192.168.1.100)

数据包如何到达? 任意一个物理口收到数据包,操作系统都会将其 "内部合并",上层应用看到的只是 bond0 接口,完全不感知具体是哪个物理口收到的。网络层协议本身并不关心物理拓扑。

场景二:多网口配置不同 IP
复制代码
服务器 A 配置:
  - eth0(IP: 192.168.1.100)
  - eth1(IP: 192.168.2.100)

**数据包如何到达?**虽然 IP 地址不同,但以太网协议仍然只保证 "数据包能到达目标 IP 对应的主机"。具体走哪条物理链路,取决于:

  • 路由表配置
  • ARP 表映射
  • 网络哈希算法(如 ECMP 多路径负载均衡)

**关键问题:**以太网协议本身并没有强制约束 "数据包必须从特定的物理口进入"。它更关注的是 "包能到达目标主机就行"。

1.3 传统以太网的性能瓶颈

当数据包到达网卡后,操作系统需要完成以下流程:

复制代码
1. 网卡触发硬件中断
2. CPU 响应中断,执行中断处理程序
3. 内核将数据包从网卡缓冲区拷贝到内核缓冲区
4. 根据 TCP/UDP 端口号,找到目标进程
5. 将数据从内核缓冲区拷贝到用户空间缓冲区
6. 唤醒目标进程

核心瓶颈:

  • 多次中断:每个数据包都会触发 CPU 中断
  • 多次拷贝:数据在内核态与用户态之间来回拷贝
  • 协议栈开销:TCP/IP 协议栈的封包 / 解包需要 CPU 参与

**根本原因:**传统以太网的寻址粒度停留在 "主机级别",无法将数据直接定向到具体的内存区域,必须依赖 CPU 进行中间转发。


二、RDMA:细粒度的 "端口级" 寻址

RDMA 的设计哲学完全不同。在 RDMA 的世界里,不存在 "主机" 这个模糊概念,只有一个个具体的 "物理端口"

2.1 RDMA 的两种核心标识符

GID(Global Identifier,全局标识符)

结构组成:

复制代码
GID = 子网前缀(64-bit) + 接口 ID(64-bit GUID)
      ├─ 标识网段           └─ 烧录在物理端口的全球唯一码

示例:

复制代码
GID: fe80::0002:c903:0000:1491
     ├─ fe80::              → 链路本地子网前缀
     └─ 0002:c903:0000:1491 → 物理端口的 GUID

**关键机制:**GUID(Globally Unique Identifier)是在网卡生产时烧录在硬件中的全球唯一标识码。每个物理端口都有独立的 GUID。

**实际含义:**当你指定目的 GID 时,你实际上是在说:

"我要找 X 子网下的 3 号物理端口(GUID = 0002:c903:0000:1491)"

这就是 "端口级寻址" 的本质 ------ GID 已经锁定了具体的物理端口,而不仅仅是网段。


LID(Local Identifier,本地标识符)

分配机制:

RDMA 网络中有一个核心组件叫 子网管理器,负责网络拓扑发现和路径计算。SM 在启动时会执行以下流程:

复制代码
1. 扫描整个网络拓扑
2. 发现所有交换机及其端口
3. 发现所有终端节点的物理端口
4. 为每个物理端口分配一个 LID(范围:1-49151)

SM 看到的网络视图:

复制代码
交换机 1:
  ├─ 端口 1 → 连接 服务器 A 的端口 P1(分配 LID = 10)
  ├─ 端口 2 → 连接 服务器 B 的端口 P2(分配 LID = 11)
  └─ 端口 3 → 连接 服务器 C 的端口 P3(分配 LID = 12)

交换机 2:
  ├─ 端口 1 → 连接 交换机 1(级联端口)
  └─ 端口 2 → 连接 服务器 D 的端口 P4(分配 LID = 13)

**LID 的含义:**LID 是物理端口在本地子网中的 "短号",类似电话通讯录中的快捷拨号。交换机在转发数据时,直接根据 LID 进行路由,无需解析复杂的 IP 地址。

关键点: LID 直接绑定到物理端口,而不是主机。如果一台服务器有两个 RDMA 端口,它们会被分配两个不同的 LID。


2.2 RDMA 的完整寻址层次

RDMA 的寻址体系比传统以太网更加细粒度:

复制代码
应用层
    ↓  标识进程的通信端点
传输层
    ↓  完全由硬件管理的发送/接收队列
网络层(GID / LID)
    ↓  定位到具体的物理端口
链路层
    ↓  物理链路上的虚拟通道
物理层(物理端口)

核心创新: 引入了 Queue Pair(QP) 的概念,每个 QP 由一个 24-bit 的 QPN 标识。应用进程在通信前,先在网卡硬件中创建 QP,后续所有数据传输都通过 QP 直接进行,无需 CPU 参与


三、RDMA 为何能做到 CPU 零拷贝?

3.1 传统以太网 vs RDMA 数据路径对比

传统以太网数据路径:
复制代码
发送方:
应用缓冲区(用户态)
    ↓ CPU 拷贝
内核缓冲区(内核态)
    ↓ CPU 封包
网卡缓冲区
    ↓ DMA
物理链路

接收方:
物理链路
    ↓ DMA
网卡缓冲区
    ↓ 中断 + CPU 拷贝
内核缓冲区(内核态)
    ↓ CPU 拷贝
应用缓冲区(用户态)

统计: 一次完整的网络通信,数据至少被拷贝 4 次 ,CPU 参与 多次中断


RDMA 数据路径:
复制代码
发送方:
应用缓冲区(用户态)
    ↓ 网卡直接 DMA 读取
物理链路

接收方:
物理链路
    ↓ 网卡直接 DMA 写入
应用缓冲区(用户态)

统计: 数据只被拷贝 1 次 (网卡 DMA),CPU 零中断


3.2 RDMA 实现零拷贝的关键机制

机制一:精确的端口级寻址(LID/GID)

当数据包到达交换机时:

复制代码
1. 交换机解析数据包的 LID
2. 根据路由表直接转发到目标物理端口
3. 数据包精准到达目标网卡的物理口

不需要 CPU 参与路由决策 ------ 交换机硬件直接根据 LID 转发。


机制二:QP 硬件队列

每个应用进程在网卡硬件中创建自己的 QP:

复制代码
QP 结构:
  ├─ 发送队列(SQ, Send Queue)
  ├─ 接收队列(RQ, Receive Queue)
  └─ 完成队列(CQ, Completion Queue)

数据接收流程:

复制代码
1. 远程主机发起 RDMA Write 操作
2. 数据包携带:
   - 目标 LID(定位到物理端口)
   - 目标 QPN(定位到 QP)
   - 目标内存地址(远程已注册的 MR)
3. 本地网卡硬件:
   - 解析 LID,确认是本端口接收
   - 解析 QPN,找到目标 QP
   - 直接通过 DMA 将数据写入应用内存
4. 写入完成后,网卡更新 CQ(完成队列)
5. 应用进程轮询 CQ 发现数据已到达

全程无 CPU 参与,无内存拷贝。


3.3 RDMA 三种操作模式对比

操作类型 发送方 CPU 参与 接收方 CPU 参与 内存拷贝次数 适用场景
Send/Recv 需要(准备数据) 需要(处理数据) 0 次 控制消息、小数据
RDMA Write 需要(发起写) 零参与 0 次 大数据传输、日志复制
RDMA Read 需要(发起读) 零参与 0 次 远程内存访问、分布式缓存

**RDMA Write/Read 的革命性:**接收方 CPU 完全不需要知道数据何时到达 ------ 数据已经被网卡直接写入内存。这种机制是分布式存储系统实现低延迟的核心。


四、为何 RDMA 必须精确到端口?

4.1 绕过 CPU 的前提条件

传统以太网需要 CPU 参与,是因为:

复制代码
问题 1:数据包到达网卡,CPU 不知道该给哪个进程
解决方案:CPU 查 TCP/UDP 端口号,找到目标进程

问题 2:CPU 不知道数据该放在内存的哪个位置
解决方案:CPU 分配内核缓冲区,再拷贝到用户空间

RDMA 的解决方式:

复制代码
1. 数据包携带目标 LID(精确到物理端口)
   → 网卡硬件确认:这个包是给我的

2. 数据包携带目标 QPN(精确到 QP)
   → 网卡硬件确认:这个包属于 QP-12345

3. 数据包携带目标内存地址(远程已注册的 MR)
   → 网卡硬件确认:数据直接写入内存地址 0x7f3a2b1000

4. 网卡通过 DMA 完成写入,更新 CQ
   → 应用进程轮询 CQ 发现数据已到达

发送方首先主动建立连接(通过 TCP Socket 或 RDMA CM 交换双方的 QP、LID/GID 等信息),连接完成后,发送方发送一个请求消息告诉接收方 "我要给你写数据",接收方收到请求后,在自己的内存中注册缓冲区并获得 rkey 和地址,然后通过 Send 操作把这些信息返回给发送方,发送方拿到地址和密钥后,才能发起 RDMA Write 直接写入接收方内存 ------ 整个过程由发送方主动驱动,接收方只是被动响应,并非 "凭空知道要发给谁"。

**关键点:**端口级寻址(LID/GID)是硬件能够直接处理数据包的前提。如果只定位到 "主机",网卡硬件无法确定数据归属,必须退回到 CPU 处理。


4.2 提供确定性的网络路径

在高性能计算场景中,网络路径的确定性至关重要。

场景:多网络拓扑的服务器
复制代码
服务器 A 配置:
  ├─ RDMA 端口 P1 → 连接存储网络(低延迟)
  └─ RDMA 端口 P2 → 连接计算网络(高吞吐)

传统以太网的问题:

复制代码
ECMP(等价多路径路由)可能随机选择物理路径:
- 第 1 个数据包走 eth0(存储网络)
- 第 2 个数据包走 eth1(计算网络)

问题:
- 乱序到达(TCP 需要重排序)
- 延迟抖动(不同路径延迟不同)
- 无法针对性优化(存储流量应该走低延迟路径)

RDMA 的解决方案:

复制代码
应用层明确指定:
- 存储流量 → 使用 GID-LID 指定走 P1 端口
- 计算流量 → 使用 GID-LID 指定走 P2 端口

结果:
- 路径确定性:数据严格走指定端口
- 零乱序:同一流的包都走同一路径
- 可针对性优化:不同流量走不同拓扑

4.3 支持大规模横向扩展

在超大规模数据中心(如 10 万台服务器)中,传统以太网面临:

复制代码
问题 1:ARP 表爆炸(每台主机都要维护大量 MAC-IP 映射)
问题 2:路由表爆炸(核心交换机路由表项过多)
问题 3:广播风暴(ARP 请求泛洪)

RDMA 通过 LID 和子网管理器(SM)解决了这些问题:

复制代码
1. SM 集中管理拓扑:所有 LID 由 SM 统一分配,无需广播
2. LID 路由简化:LID 是线性地址,路由表计算简单
3. 分层子网设计:不同子网通过路由器连接,控制广播域

**核心优势:**端口级寻址让 RDMA 网络在大规模场景下仍保持高效可控。


五、核心技术对比总结

5.1 寻址粒度对比

维度 传统以太网 RDMA
网络层标识 IP 地址(定位到主机) GID/LID(定位到物理端口)
传输层标识 TCP/UDP 端口号(内核态维护) QPN(硬件态维护)
寻址粒度 主机级(粗粒度) 端口级(细粒度)
拓扑感知 弱(IP 协议不关心物理拓扑) 强(SM 精确掌握物理拓扑)
路径控制 弱(依赖路由协议自动选择) 强(可明确指定物理路径)

5.2 数据路径对比

对比项 传统以太网 RDMA
数据拷贝次数 4 次(应用↔内核↔网卡) 1 次(应用↔网卡)
CPU 中断次数 每包至少 1 次 0 次(轮询模式)
协议栈开销 高(TCP/IP 封包 / 解包) 低(硬件直接处理)
延迟 微秒级(10-100μs) 亚微秒级(1-10μs)

5.3 适用场景对比

场景 传统以太网 RDMA
普通 Web 服务 ✅ 适用(成本敏感) ❌ 过度设计
数据库应用 ✅ 适用(通用场景) ⚠️ 高端场景可选
分布式存储 ⚠️ 可用但性能受限 ✅ 高度推荐(如 Ceph RDMA)
高性能计算 ❌ 性能不足 ✅ 必选(如 MPI over RDMA)
AI 训练集群 ⚠️ 可用但效率低 ✅ 必选(如 NCCL RDMA)
金融低延迟交易 ❌ 延迟过高 ✅ 必选

六、实际案例:RDMA 在分布式存储中的应用

Ceph 分布式存储系统 为例,对比传统 TCP 和 RDMA 的性能差异。

6.1 测试环境

复制代码
硬件配置:
- 服务器数量:12 台
- 每台服务器:2× RDMA 网卡(Mellanox ConnectX-5,100Gbps)
- 存储介质:NVMe SSD

网络拓扑:
- 全交换架构,所有节点全互联
- SM 使用 OpenSM(开源子网管理器)

6.2 性能对比结果

测试场景 TCP(10Gbps) RDMA(100Gbps) 性能提升
4K 随机读 50K IOPS 450K IOPS 9 倍
4K 随机写 30K IOPS 380K IOPS 12.6 倍
顺序读(128KB) 800 MB/s 9.5 GB/s 11.9 倍
平均延迟 120 μs 15 μs 降低 87.5%
CPU 利用率 85% 25% 降低 70%

6.3 关键观察

  1. **延迟降低 87.5%**CPU 零拷贝和零中断直接体现在延迟指标上。

  2. **CPU 利用率降低 70%**数据平面完全由网卡硬件处理,CPU 可以专注于业务逻辑。

  3. 吞吐接近线速100Gbps RDMA 网卡实测吞吐达到理论带宽的 95% 以上。


0voice · GitHub

相关推荐
zzzsde2 小时前
【Linux】进程控制(1):进程创建&&进程终止
linux·运维·服务器
sugar__salt2 小时前
网络原理(五)——HTTP
网络·网络协议·http
顺顺 尼2 小时前
linux第一个系统程序-进度条
linux
謓泽2 小时前
【MODBUS】串口 RTU / Modbus TCP / 透明就绪
网络·串口·modbus
开源盛世!!3 小时前
3.19-3.21
linux·服务器·前端
小民AI实战笔记3 小时前
htop安装不了怎么解决
linux·运维
budingxiaomoli3 小时前
数据链路层&&应用层知识总结
网络
Predestination王瀞潞3 小时前
5.4.1 通信->WWW万维网内容访问标准(W3C):WWW(World Wide Web)基本信息&核心设计目标&现实意义
css·网络·网络协议·html·url·www
源远流长jerry3 小时前
RDMA 技术深度解析:从原理到实践
linux·网络·tcp/ip·架构·ip