Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature]: Supports RDMA features #3310

Open
1 task done
leonrayang opened this issue Apr 11, 2024 · 1 comment
Open
1 task done

[Feature]: Supports RDMA features #3310

leonrayang opened this issue Apr 11, 2024 · 1 comment
Assignees
Labels
enhancement New feature or request

Comments

@leonrayang
Copy link
Member

Contact Details

No response

Is there an existing issue for this?

  • I have searched all the existing issues

Is your feature request related to a problem? Please describe.

As servers are being upgraded, there is an increasing proportion of hardware support for RoCE (RDMA over Converged Ethernet) network cards. The RDMA protocol offers better congestion control and lower latency. Adapting distributed file systems to utilize RDMA can enhance overall throughput.

Describe the solution you'd like.

RDMA模块简介

RDMA意为远程直接地址访问,即本端节点可以像访问本地内存一样,绕过复杂的TCP/IP网络协议栈直接读写远端内存。RDMA技术可以用于构建高性能的存储网络,提供低延迟和高带宽的存储访问,因此为了提高CubeFS在大模型场景中的写入速度,开发了RDMA模块以减少cpu消耗,加速数据传输和降低通信延迟,并优先解决写入流程。

RDMA技术优势:

  • 零拷贝:应用程序可以在不涉及网络软件堆栈的情况下执行数据传输。数据直接发送和接收到缓冲区,而无需在网络层之间复制。
  • 内核旁路:应用程序可以直接从用户空间执行数据传输,无需内核参与。用户空间直接将数据发送或接收任务添加到硬件任务队列,然后通过硬件中断通知硬件进行处理。
  • 无需CPU参与:应用程序可以访问远程内存,而不消耗远程服务器中的任何 CPU 时间。远程内存服务器将在没有远程进程(或处理器)的任何干预的情况下被读取。而且,远程CPU的缓存不会被所访问的内存内容填满。内存操作都是由DMA控制器处理,不需要CPU参与。

CubeFS RDMA方案设计:

为了适配GDS场景,控制消息使用send和recv这一组操作实现,而数据载荷部分是数据传输的主要内容,所以使用read和write这类对端无感知的操作来实现, 在客户端数据写入流程中,由接收消息头的一端主动到另一端拉取数据;而在客户端数据读取流程中,由接收消息头的一段主动将数据写到远端。

1.客户端写数据到服务端流程:

  • client先向dataNode leader发送(rdma send)消息头,其中包含了数据内存地址和秘钥等信息。
  • dataNode leader接收(rdma recv)对端发送的消息头。
  • dataNode leader根据消息头中的size从内存池上分配一块本地内存,从客户端读取(rdma read)消息头中指定的远端内存数据到该本地内存。
  • dataNode leader读取成功后,写磁盘持久化。同时向两个dataNode follower也发送(rdma send)消息头。
  • 两个dataNode follower接收(rdma recv)对端发送的消息头。
  • 两个dataNode follower根据消息头中的size分别从内存池上分配一块本地内存,从leader读取(rdma read)消息头中指定的远端内存数据到该本地内存。
  • 两个dataNode follower读取成功后,写磁盘持久化。完成之后将保存数据的本地内存放回内存池。
  • 两个dataNode follower向dataNode leader发送(rdma send)响应,以告知dataNode leader本次消息已被处理完毕。
  • dataNode leader接收(rdma recv)到两个dataNode follower的响应之后,确认该块本地内存上的数据已被处理完毕,将保存数据的本地内存放回内存池。
  • dataNode leader向客户端发送(rdma send)响应。
  • 客户端接收(rdma recv)到dataNode leader的响应之后,确认数据内存上的数据已写入成功dataNode,释放内存到内存池中。

2.客户端从服务端读数据流程:

  • 客户端先向dataNode leader发送(rdma send)消息头,其中包含数据内存地址和秘钥等信息。
  • dataNode leader接收(rdma recv)对端发送的消息头。
  • dataNode leader根据消息头中的size从内存池上分配一块本地内存,并从磁盘中读取数据到该内存中。
  • dataNode leader将本地内存中的数据写入(rdma write)到消息头指定的客户端远端内存中。
  • dataNode leader写入成功后,向客户端发送(rdma send)响应。
  • 客户端接收(rdma recv)到dataNode leader的响应之后,确认客户端已成功读取到数据。

3.数据内存:

数据内存实现为内存池,并且使用buddy算法进行内存分配,每次进行通信的时候都先从内存池中分配一块足够大小的内存用来保存读取或者写入的数据,而当上层应用处理完成之后,就将该内存释放回内存池。由于dataNode leader需要同时作为client的接收端以及follower的发送端,所以需要在dataNode leader跨连接时共享数据内存以避免数据载荷的多次拷贝,即使dataNode leader面向client的接收端连接和面向follower的发送端连接注册相同的内存池,这样就省去了去了内存拷贝的消耗。

4.控制内存:

在客户端和服务端分别注册一块用于传递控制信息的控制内存,它的作用主要有:固定长度的消息头和响应都从其上分配内存,连接建立之初同时注册多个消息头和响应的内存块以同时接收和发送多个消息。这些块可以分为两个部分:

  • max_recv_wr个块用于接收,客户端和服务端在初始化的时候就会提交在这些内存块上的接收请求到接收队列中,它们一直在等待接收来自发送端的消息,接收完成之后会再次提交接收请求等待接收。
  • max_send_wr个块用于发送,初始化之后其状态为available,当需要发送的时候会从从中找到一个available的块来提交发送请求,发送完之后将其重置为available状态。

Describe an alternate solution.

No response

Anything else? (Additional Context)

No response

@leonrayang leonrayang added the enhancement New feature or request label Apr 11, 2024
@leonrayang
Copy link
Member Author

@shuqiang-zheng Please translated into English, supplementary pictures

@cubefs cubefs deleted a comment from github-actions bot Apr 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants