总目标
要做的事 = 用 RDMA 原生接口(Verbs)写 C 代码
把本地 1GB 文件读到内存
通过 RDMA 发给另一台机器
记录时间 → 算出传输速度(MB/s)
一、必须懂的 RDMA 最核心概念(只记这 9 个)
1.RDMA 是什么
直接内存访问,不经过 CPU、不经过内核协议栈,两台机器内存直接互传。
2.RC 可靠连接
你传文件必须用 RC(Reliable Connected)
可靠:丢包会重传
连接模式:像 TCP 一样先建连再发数据
传文件 = 必须用 RC
3.QP(Queue Pair)
RDMA 通信的“端点”,相当于 TCP 的 socket。
发数据、收数据都靠它。
4 MR(Memory Region)内存注册
RDMA 不能直接随便用内存,必须先注册:
注册 = 告诉网卡:这段内存我要用来收发数据
你传 1GB 文件,必须先把文件所在内存注册成 MR。
5 L_Key / R_Key
内存权限钥匙,网卡收发数据需要这个钥匙。
6 Send / Recv(消息收发)
你传文件用的最简单模式:
客户端 send
服务端 recv
就像 TCP 的 send/recv,但零拷贝、极快。
7 Completion Queue (CQ)
通知你:数据发完了 / 收到了
没有 CQ 你不知道什么时候传完。
8 Address Handle (AH)
存放对方地址信息(GID、IP 等)。
9 RDMA 两大操作(你只用第一种)
Send/Recv:简单、稳定、适合传文件
RDMA Write/Read:高级、点对点读写
小白传文件:优先用 Send/Recv
二、必须懂的 RDMA 通信流程
这是你写代码的框架,所有 RDMA 程序都长这样:
服务端(被动等待)
打开 RDMA 网卡设备
创建 CQ(完成队列)
创建 QP(队列对)
切换 QP 状态 → Ready
注册内存 MR
等待客户端连接
循环 Recv 接收 1GB 文件数据
接收完成,计算速度
客户端(主动发送)
打开 RDMA 网卡设备
创建 CQ
创建 QP
连接服务端
读取 1GB 文件到内存
注册内存 MR
循环 Send 发送全部数据
发送完成,计算速度
三、必须会用的 RDMA 函数
ibv_open_device 打开网卡
ibv_alloc_pd 申请保护域(必须)
ibv_create_cq 创建完成队列
ibv_create_qp 创建 QP
ibv_modify_qp 设置 QP 状态
ibv_reg_mr 注册内存(最关键!)
ibv_post_send 发送数据
ibv_post_recv 接收数据
ibv_poll_cq 等待完成(发完/收完)
ibv_destroy_qp 清理资源
你不用理解底层原理,会按顺序调用就行。
四、必须懂的数据结构
struct ibv_qp_init_attr QP 属性
struct ibv_send_wr 发送请求
struct ibv_recv_wr 接收请求
你只需要知道:
发数据前,填好 send_wr
收数据前,填好 recv_wr
五、传 1GB 文件必须知道的工程细节
这些决定你能不能跑通:
不能一次 send 1GB 网卡有最大消息限制,一般 4KB ~ 1MB 一块 你要:
把 1GB 文件切成 4KB 或 1MB
循环 send / recv
直到传完 1GB
必须等前一个发送完成,再发下一个 ;用 poll_cq 等待完成。
测速方法
开始时间 = 发送前
结束时间 = 最后一块发送完成
速度(MB/s) = 1024MB / (结束 - 开始)
文件操作 用标准 C 语言:
open / read 把文件读到内存
write 把收到的数据写入新文件
六、你必须搭建的环境(最简)
两台带 RDMA 网卡的服务器(ConnectX-4/5/6)
直连网线(不用交换机,最简单)
Linux 系统(Ubuntu/CentOS)
安装依赖:
# Ubuntu
sudo apt install libibverbs-dev rdma-core
# CentOS
sudo yum install libibverbs-devel rdma-core
参考链接 :0voice · GitHub