cyf31头像
关注

RDMA数据传输原理深入解读

没有真实RDMA网卡也能学!本文手把手教你用两台VMware Ubuntu虚拟机搭建Soft-RoCE模拟RoCEv2环境,完整运行ib_send_bw带宽测试,并基于Wireshark抓包深入拆解RDMA报文交互全过程。从ARP广播、TCP控制面建连,到RC Send大消息拆包(First→Middle→Last)、ACK确认机制,再到AETH流控信用值、PSN序列号、QP状态机——一文讲透RDMA可靠连接(RC)的数据面与控制面交互原理。适合网络工程师、存储开发、AI基础设施从业者入门RDMA技术栈。

关键词:RDMA、RoCEv2、Soft-RoCE、ib_send_bw、perftest、Wireshark抓包、RC可靠连接、QP状态机、BTH、AETH、VMware Ubuntu、RDMA原理、零拷贝网络

1、RDMA测试环境准备

1)两台 VM:

  • Node-A:192.168.95.128,网卡 ens33,主机名 node-a
  • Node-B:192.168.95.130,网卡 ens33,主机名 node-b
  • 已加载 rdma_rxe,已用 rdma link add rxe_0 type rxe netdev ens33 绑定业务网卡
  • 已装 rdma-core / ibverbs-utils / perftest 等 RDMA 软件栈
  • 普通 IP 已互 ping 通,UDP 4791 未屏蔽

2)验收三条命令:

# 两端rdma link show# 期望:link rxe_0/1 state ACTIVE physical_state LINK_UP netdev ens33ibv_devinfo -d rxe_0# 期望 port 1 state PORT_ACTIVE,link_layer Ethernet;Soft-RoCE 常 active_mtu=1024 

防火墙放 RoCEv2 数据面:
sudo ufw allow 4791/udp

2、ib_send_bw测试结果

1)服务端 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

2)测试结果分析:

从测试结果可以看到,服务端:只起监听、post recv(收),不主动发业务数据

ib_send_bw -d rxe_0 -x 2 ...

客户端:连服务端、post send(发),测“客户端→服务端”的 Send 带宽

ib_send_bw -d rxe_0 -x 2 ... 服务端IP

perftest 官方对 send_bw 的描述就是 server 收、client 发,算吞吐;RC 模式下服务端也要 poll CQ 收完成,但业务数据方向默认是客户端→服务端。 默认 RC、默认单向;要双向加 -b(bidirectional)。

3)ib_send_bw是否需要CPU参与?

Send 不像 Write/Read 那样只靠 RKey 写远端内存,它要求:

客户端 SQ 里 post send WQE

服务端 RQ 里提前 post recv WQE

数据到对端后匹配 recv buffer,再出 CQE。两端 CPU 都要参与(发端发、收端收+poll),所以叫双边;但“双边”不等于“双向”,默认仍只发一个方向。

4、测试参数解读

关键字段深度解读

1. local address / remote address 中的 GID

  • 格式:254:128:00:00:00:00:00:00:XX:XX:XX:XX:XX:XX:XX:XX
  • 这是 IPv6 格式的 RoCEv2 GID,前 8 字节固定为 fe80::(链路本地地址前缀),后 8 字节由 MAC 地址或 IPv4 地址转换而来。
  • 虽然你用的是 IPv4 地址(192.168.95.128),但 RoCEv2 的 GID 仍以 IPv6 格式呈现,Wireshark 中也会显示为 fe80::...。
  • -x 2 指定使用 IPv4 类型的 GID index 2,所以实际通信基于 IPv4,但 GID 本身是 IPv6 格式。

2. LID 0000

  • LID(Local Identifier)是 InfiniBand 子网内的 16 位地址,用于 IB 模式寻址。
  • Soft-RoCE 运行在以太网上,没有 IB 子网管理器,因此 LID 始终为 0。
  • 真机 IB 网络中 LID 非零,RoCE 环境下 LID 也为 0。

3. QPN 0x0011

  • QP 编号,范围 0x0001~0xFFFF。
  • 两端 QPN 恰好相同(0x0011),这是巧合,不影响通信。
  • 每个 QP 唯一标识一条连接。

4. PSN(Packet Sequence Number)

  • 初始 PSN 随机生成,之后每发送一个包递增。
  • 服务端 PSN=0x1d9c33,客户端 PSN=0xf6a92d,两者独立。
  • RC 模式下,接收端通过 PSN 检测丢包和乱序,并触发重传。

5、抓包深入分析RDMA通信原理和交互过程

1)Ib_send总共发送1000次数据,每次数据量64KB,由于MTU是1024B,所以64KB的数据块会拆分成64个RDMA报文进行发送。

2)以下是报文交互抓包截图(共52849个RDMA报文):

1~6:ARP广播报文

7~37:RDMA控制面报文,TCP建链报文

38~52837:RDMA数据发送报文,RDMA报文

52838~52849:RDMA控制面报文,TCP断链报文

1. 前 6 个 ARP 广播报文

  • 原因:虚拟机网卡(MAC 地址为 VMware_c0:00:08)在发起通信前,需要知道目标 IP(192.168.95.27,通常是网关或同网段测试对端)的 MAC 地址。
  • 作用:通过广播 ARP Request(Who has 192.168.95.27 Tell 192.168.95.1)进行地址解析,这是以太网通信的标准前置动作。

2. 第 7 到 37 个 TCP 报文

  • 原因:perftest 工具(包含 ib_send_bw)在默认情况下不使用 RDMA CM(除非加了 -R 参数),而是自己开一条普通的 TCP Socket 控制连接来进行带外握手。
  • 作用:RDMA 的可靠连接(RC)在真正发数据前,两端必须交换核心连接参数,包括双方的 QP 号(QPN)、起始包序列号(PSN)、全局标识符(GID)、内存密钥(RKey)和缓冲区地址等。TCP 连接(图中使用端口 18515)就是用来完成这个“建连协商”的。
  • 细节:图中 7-9 是 TCP 三次握手,10-37 是双方通过 TCP 发送协商参数(包含 PSH 数据标志),最后通过 TCP 四次挥手(或测试结束后的断开)关闭控制连接。

3. 第 38 个报文开始是 RC Send 报文

  • 原因:当 TCP 控制面完成参数交换,并将 QP(队列对)状态机切换到 RTS(Ready To Send,就绪发送态)​ 后,真正的 RDMA 数据面传输才开始。
  • 特征:此时数据完全绕过内核 TCP/IP 协议栈,由网卡硬件直接封装成 RoCEv2 报文(UDP 端口 4791)。图中显示为 RC Send First 和 RC Send Middle,这就是客户端向服务端单向发送的 RDMA 业务测试数据。

4. 大消息拆包(First + Middle... + Last)

  • 现象:第38个是 RC Send First,第39-100个是 RC Send Middle,第101个是 RC Send Last。
  • 原因:ib_send_bw 默认会发送一条较大的测试消息(例如你之前提到的 64KB)。而以太网有 MTU(最大传输单元)限制(例如 1024 或 4096 字节)。网卡硬件会自动将这条大消息拆分成多个小包进行发送。
  • 字段含义:
    • First:拆分的第一个包。它除了携带数据载荷外,还包含关键的 RETH(RDMA 扩展传输头),里面记录了远程内存地址、RKey 等信息(如果是 Write 操作)。
    • Middle:拆分的中间数据分片。只携带纯数据载荷,没有 RETH 头。
    • Last:拆分的最后一个包,标志着这条大消息传输结束。
  • PSN 递增:在这个过程中,每个包的 BTH 头部里都有一个 PSN(包序列号)​ 在严格递增(模 2^24),用于保证收发顺序和丢包检测。

5. 可靠确认(RC Acknowledge)

  • 现象:第102个是 RC Acknowledge 报文。
  • 原因:RC(可靠连接)模式类似于 TCP,需要接收端给发送端回确认信。接收端网卡(服务端)在成功按序收到这一整条消息(从 First 到 Last,PSN 连续无缺失)后,会向发送端网卡(客户端)回复一个 ACK 报文。
  • 机制:这个 ACK 报文里包含了 AETH(确认扩展传输头),告诉发送端“我已经成功收到了截止到某个 PSN 的所有数据”。如果中间丢了包,接收端会回 NAK,触发发送端的 Go-Back-N 重传机制。

6. 触发确认(AckReq 标志)

  • 细节:你可能在 Wireshark 里展开第101个 RC Send Last 包,会发现 BTH 头部里有一个 AckReq(请求确认)​ 标志位被置 1。
  • 作用:发送端在发送关键包(通常是消息的最后一个包,或者按一定窗口间隔)时,会要求接收端必须立刻回复 ACK。这就是为什么 ACK 紧跟在 Last 包之后立刻出现的原因。

7. 下一条消息的传输(循环)

  • 现象:第103个开始又是 RC Send First。
  • 原因:ib_send_bw 是一个带宽测试工具,它会连续不断地发送多条测试消息。当第一条消息完成传输并确认后,网卡立刻开始拆包并发送第二条测试消息,周而复始。

8. 第 52038~52045 个报文:TCP 控制连接断开

  • 背景:正如之前提到的,ib_send_bw 在测试前会通过 TCP 端口(如 18515)建立一条控制连接,用来交换 QP 号、PSN、RKey 等核心参数。
  • 交互过程:当 RDMA 数据测试完成(第 52037 个报文是最后一条消息的 ACK)后,测试工具(perftest)正常退出,TCP 控制连接也随之关闭:
    • 52038-52040:.130(客户端)向 .128(服务端)发送带有 [FIN, PSH, ACK] 的报文。其中 FIN 表示发送方数据已发送完毕,请求关闭连接;PSH 提示将剩余数据立刻交给应用层;ACK 确认收到之前的数据。
    • 52041-52042:.128(服务端)回复 [ACK] 确认客户端的断开请求,并也发送了自己的 [FIN, PSH, ACK] 请求关闭反向连接。
    • 52043:.130 回复 [ACK] 确认服务端的 FIN。
    • 52044-52045:.130 又发送了 [RST, ACK]。RST 表示强制重置/断开连接。在 TCP 中,当程序快速退出、端口关闭或连接异常时,常会发送 RST 来立即释放连接资源,跳过标准的 TIME_WAIT 等待状态。

6、RDMA报文解析

1)RC Send First报文

重点看一下UDP头和BTH头

a)UDP头:

端口:源端口 57236(随机高位端口),目的端口 4791。4791 是 IANA 分配给 RoCEv2 的官方固定端口,Wireshark 借此识别出其上层协议为 InfiniBand/RDMA。

b)BTH头:

BTH 是 RDMA 报文必须携带的 12 字节基础头部,核心字段如下:

  • Opcode: Reliable Connection (RC) - SEND First (0):
    • RC(可靠连接):表示这条连接是点对点、保序且可靠的,需要接收端回 ACK 确认。
    • SEND First:表示这是双边 Send 操作大消息拆分之后的第一个分片包。它携带了消息的初始数据,后续会跟随 SEND Middle 和 SEND Last 包。
  • Destination Queue Pair (QP): 0x000011:目的端队列对号。RDMA 通信通过 QP 进行,数据被投递到对端的这个特定 QP 中。
  • Packet Sequence Number (PSN): 858106:包序列号。RC 服务用 PSN 来严格保证包的顺序交付和丢包检测重传。
  • Partition Key (PKey): 65535:分区键(默认全权限分区)。
  • Acknowledge Request: False:当前首包未强制请求立即确认(通常会在最后的 SEND Last 包中将该位置为 True,要求对端回复 ACK)。

RC Send Middle报文除了PSN编号增长,其他字段与RC Send First相同

RC Send Last的Acknowledge Request字段为true。

2)RC Acknowledge报文

a)BTH头:

  • Opcode: Reliable Connection (RC) - Acknowledge (17):明确标识这是 RC 服务的 ACK 报文。
  • Destination Queue Pair: 0x000011:确认报文发往发送端的 QP 11。
  • Packet Sequence Number (PSN): 858169:核心字段。这个 PSN 对应发送端最后发出的那个包的序列号。接收端通过此字段告知发送端:“截止到 858169 号包的数据我已全部按序收到”。

b)确认扩展头(AETH):

AETH 是 ACK 报文特有的扩展头,用于传达确认状态和流控信息:

  • Syndrome: 31, Ack:确认状态码。31 表示正常的正确认(ACK)。如果是丢包或错误,这里会显示 NAK 及相关错误码。
  • Credit Count: 31:流控信用值。相当于接收端告诉发送端“我的接收缓冲区还剩 31 个包的容量,你可以继续发”。这是 RC 可靠传输和流控机制的关键部分。
  • Message Sequence Number: 1:消息序列号,用于标记确认的是第几条消息。

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/cyf31/article/details/167170708

文章来源转载

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--