NVMe over Fabrics又让RDMA技术火了一把

本文深入浅出地介绍了RDMA技术的基本原理及其在网络存储系统中的应用。RDMA允许数据在两个节点间直接传输,无需主机CPU干预,从而显著降低延迟并提高效率。文章还探讨了RDMA在NVMe over Fabrics中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RDMA是个什么鬼?相信大部分不关心高性能网络的童鞋都不太了解。但是NVMe over Fabrics的出现让搞存储的不得不抽出时间来看看这个东西,这篇文章就来介绍下我所了解的RDMA。

RDMA(Remote Direct Memory Access)意为在远端直接访问主机的内存,而不需要主机参与。如下图,当主机和Client端都配备RDMA NIC的时候,数据通过NIC的DMA引擎直接在两端内存之间转移,而不需要经过OS的网络协议栈。这种技术对于局域网高带宽的存储系统非常有吸引力。

网络技术中,协议是必不可少的部分。RDMA环境下,传统的TCP/IP协议过于庞大,所以需要一种特殊的协议来发挥其优势,这就是InfiniBand协议(简称IB)。InfiniBand定义了一套完整的IB框架,这个框架中有我们在以太网中了解的大部分概念:交换机,路由器,子网络等。

虽然InfiniBand看起来非常不错,但是组建一个IB网络,尤其当网络拓扑比较复杂的时候,对于习惯以太网的用户来说,在技术和成本方面花销太大。为了适应这方面的需求,IB组织在IB协议基础上增加了适用于以太网的协议:ROCE和iWARP。使用这两类协议就可以通过普通的以太网硬件组网。

这些协议的关系可以看下图,其中IB性能最好,ROCE则用得最多。无论是哪种技术,都必须保证RDMA的实现。

 

简单了解了RDMA,我们与传统的网卡对比来进一步说明。

普通的网卡都是基于OS的TCP/IP技术为上层提供网络服务。在Linux内核中,有一个著名的结构体sk_buff,这个结构体用来暂时存储传输的数据,它贯穿于内核网络协议栈和网卡驱动,用户的收发数据都要经过sk_buff。可以推断,这种设计至少需要一次内存copy,再加上TCP/IP等的处理,整个下来就造成了不少的overhead(引入的Latency和CPU处理时间)。

 

RDMA在编程模型上跟Socket有几分相似之处,比如都会使用Send和Receive交换信息。在RDMA中,还有一个Queue Pair(QP)的概念,每个QP由一个Send Queue和Receive Queue组成,Send Queue用来发送数据,Receive Queue则在另一端接收数据。在进行通信前,Server和Client端都需要建立这样的Queue Pair。RDMA支持多个QP,其数量限制由对应的网卡决定。

 


QP中的传输使用Work Request(WR)进行,而非数据流的形式。应用程序在Work Request中指定收发数据的地址(RDMA对数据存放的地址有要求,这些地址在使用前,必须注册到IB驱动中)。除此之外,QP的Send Queue和Receive Queue还需要配备一个Completion Queue,这个Completion Queue用来保存WR处理结果(发送或者收到),WR信息可以从Completion Queue中的Work Completion(WC)中获得。

 

进一步讲,WR还分为Receive WR和Send WR,Receive WR用来指定另一端发过来的数据存放位置,Send WR则是实际的数据发送请求。在主机中注册的内存类型(ib_access_flags)决定了远端client操作主机内存的方式。如果具有Remote Access权限,则可以直接在Send WR中指定待操作的地址(此为RDMA Read/Write操作),主机无需参与操作;否则Send WR对远端地址没有控制权,即发送的数据的存放地址不由Send WR决定(只能Send/Recv操作),主机需要处理请求。使用哪种操作方式可以在ib_wr_opcode中指定。

 

这两种方式就是经常提到的one-sided和Two-sided。one-sided(RDMA Read/Write)相比于Two-sided的好处是释放了主机端的CPU,降低了传输的Latency。从下图可以看出,one-sided方式在主机端无需生成WQE,也就不需要处理Work Completion。

 

最后,我们回到NVMe over Fabrics,以client的一个写请求的处理过程来展示NVMf如何利用RDMA技术。

1,NVMe Queue与Client端RDMA QP一一对应,把NVMe Submission Queue中的NVMe Command存放到RDMA QP注册的内存地址中(有可能带上I/O Payload),然后通过RDMA Send Queue发送出去;

2,当Target的NIC收到Work Request后把NVMe Command DMA到Target RDMA QP注册的内存中,并在Targe的QP的Completion Queue中设置一个Work Completion。

3,Target处理Work Completion时,把NVMe Command发送到后端PCIe NVMe驱动,如果本次传输没有带上I/O Payload,则使用RDMA Read获取;

4,Target收到PCIe NVMe驱动处理结果后通过QP的Send Queue把NVMe Completion结果返回给client。

上面这个流程是当前NVMf的实现,可以看出,目前NVMe Command使用的是two-sided形式。一部分原因是Target端 CPU需要处理QP的Work Completion:将收到的NVMe 命令提交给PCIe NVMe驱动。如果把这一块能够offload,也许能够实现NVMf的one-sided传输,到时候性能会更强悍。

 

总结

这篇文章介绍了NVMf中最先实现的Transport-RDMA的部分技术细节。RDMA已经是一个成熟的技术,之前更多的是用在高性能计算中,而NVMe的出现,让它的使用范围迅速扩大。对于今天的存储从业者尤其是NVMe领域,了解RDMA技术对于跟进NVMe的发展趋势有比较大的帮助,希望这篇文章对您了解RDMA有一定的帮助,但是更多的RDMA技术细节还需要根据自己的需求去挖掘。

 

说明

本文最先发布于公众号《存储技术最前线》

 

感谢下列链接中的专家为本文中提供的素材

1, http://www.mellanox.com/pdf/whitepapers/IB_Intro_WP_190.pdf

2, How_Ethernet_RDMA_Protocols_Support_NVMe_over_Fabrics_Final,John Kim, Mellanox,under SINA.

3, RDMA programming concepts, OpenFabrics Alliance

4, https://www.zurich.ibm.com/sys/rdma/model.html

5, http://lxr.free-electrons.com/source/include/rdma/ib_verbs.h

 

相关阅读

NVMe over Fabrics:概念、应用和实现

 

转载于:https://www.cnblogs.com/rodenpark/p/6220474.html

### Linux NVMe over RDMA 软件框架实现与使用 #### 实现细节 Linux环境下的NVMe over RDMA软件框架主要依赖于内核模块和用户空间工具的支持。该框架允许通过远程直接内存存取(RDMA)协议来访问网络连接的NVMe存储设备。 为了支持这一功能,内核配置选项`CONFIG_NVME_RDMA`被启用[^1]。此配置项使得内核能够加载必要的驱动程序以处理RDMA传输层上的NVMe命令。具体来说,这涉及到初始化RDMA资源、建立到远端服务器的连接以及管理数据包的发送接收流程。 对于用户空间部分,则有专门设计的应用程序接口(API),这些API提供了创建会话、提交I/O请求等功能。例如,在应用程序层面可以通过libnvme库来进行操作,它封装了一系列用于管理和控制NVMe-oF(over Fabrics)设备的功能调用[^2]。 ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> // 假设已经包含了 libnvme 的头文件 #include "libnvme/nvme.h" int main() { struct nvme_ctrl *ctrl; // 连接到指定地址的目标控制器 ctrl = nvme_connect_target("rdma://target_address", NULL, 0); if (!ctrl) { fprintf(stderr, "Failed to connect\n"); exit(EXIT_FAILURE); } printf("Connected successfully!\n"); // 断开连接并释放资源 nvme_disconnect.ctrl(ctrl); return 0; } ``` 这段简单的C语言代码展示了如何利用libnvme库中的函数去连接一个位于特定IP地址处的RDMA目标,并打印成功消息之后断开端口链接。 #### 使用方法 要使用这个框架,开发者通常需要先安装相应的开发套件(DKMS)和支持库(libfabric等)。接着按照官方文档指导完成系统的适当设置,比如调整防墙规则以便让RDMA流量顺利通行;最后编写自己的应用逻辑或者修改现有的存储管理系统使之兼容新的通信机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值