1. 从“一次远端写入”看清楚 RDMA 把可靠性放在哪一层
RDMA 传输服务 的可靠性到底靠不靠谱?这是我在刚开始用 InfiniBand 和 RoCE 时最爱问的一句话,后来发现真正要把这个问题讲清楚,不能只看协议名,还得看你用的是哪种连接模式。很多入门材料喜欢把 RDMA 形容成“网卡直接搬内存”,这句话没错,但它让人忽略了一个关键点:从源内存到目标内存这段过程,谁来保证数据不丢、不错、不乱序?你如果把它丢给上层网络协议,RDMA 的延迟优势就没了;如果丢给 CPU,内核旁路就白做了。所以答案是:RDMA 的传输服务本身要承担很大一部分可靠性工作,这就是 RC、UC、RD、UD 这一堆缩写存在的意义。
1.1 传统网络栈的瓶颈其实不在“带宽”,而在“处理”
在说 RDMA 之前,先想想普通 TCP/IP 发一次数据要经过什么。应用把数据写进 socket buffer,内核把用户态数据拷贝到 sk_buff,经过 TCP 分段、IP 路由、网卡驱动,再触发 DMA 到网卡。数据到了对端,又得经过一次 DMA、驱动收包、协议栈处理、内核把数据拷到用户态缓冲区。这中间的每一步都有 CPU 参与,尤其是网卡断包和内存拷贝,只要吞吐一高,CPU 占用率就上去了。
传统网卡发展到后来也支持 TCP 卸载、checksum offload、LRO/GRO 这些特性,本质上都是想帮 CPU 分担协议栈工作。但真正难解决的是“数据路径”问题:数据总是要经过内核,通讯的双方不能直接访问对方内存。RDMA 的做法则直接改变了边界——让网卡(HCA)成为两个端点之间数据搬运的执行者,应用只需要注册一段内存,然后把内存地址、访问密钥告诉网卡,网卡自己把数据拆包、发送、重组,最后 DMA 写到对端应用指定的缓冲区里。
1.2 RDMA 传输层要回答的问题:谁保证可靠
很多人以为有了 RDMA,所有的丢包、重传问题都消失了,实际上不是。RDMA 把可靠性下放到了硬件传输层,但“可靠”是有等级和成本的。
一个 RDMA 消息从发送队列(SQ)发出后,会被切成大小不超过路径 MTU 的报文,每个报文都带传输层头部。接收方收到后要么向上递交,要么根据报文序号判断是不是丢了包。如果这个 RDMA 服务要求可靠交付,发送端的 HCA 就会保存发送状态、等待确认
