RDMA中间件UCX介绍
简介
UCX是Unified Communication X的简称,主要提供RDMA通信的高级API以加速应用开发,在隐藏底层细节的同时还实现了一些优化和最佳实践以保持高性能和可扩展。除了RDMA(IB和RoCE),UCX也支持包括TCP,GPU和共享内存等在内的其他传输层。UCX是一个开源项目,可以通过https://github.com/openucx/ucx访问。
优化
UCX针对RDMA的主要优化包括:
- 自动选择最优的传输层和设备
一个主机节点上往往有多张网卡和每张网卡可支持多种传输协议。UCX可以根据策略选择最优的设备和传输协议,而在最优的选择不可用时,切换到其他的组合。
- 不同大小的消息采用不同的协议
不同长度的消息采用不同的协议以达到最大的性能。比如RDMA传输过程中,小消息采用eager协议能达到较好的延迟,大消息则采用Rendezvous协议能达到较大的吞吐率。
- 内存注册缓存
在RDMA传输中,为了应用和设备能够直接通信,应用需要注册内存并告知硬件,然而内存注册/注销操作的开销比较大。内存注册缓存则在内存第一次使用时注册,而不用时并不注销而是存入缓存,再次使用时,直接从缓存获取而不需要再次注册,只有在缓存不够或者内存释放时才会真正注销。
4)端口聚合:Multi-rail & RoCE LAG
多个设备可以聚合成一个设备作为负载均衡或者冗余备份时使用。
架构
UCX处于应用和传输层软件库或者驱动之间,向应用提供高级的抽象的API屏蔽底层传输的细节。UCX内部分为两层,上层UCP暴露API给应用,定义传输协议比如eager和rendezvous,管理连接等等。下层UCT层包括各个传输的具体实现和优化,为UCP提供一个统一抽象的传输层。
对象
UCX定义了几个主要的对象,API基本都是对这些对象的操作和处理:
- ucp_context_h:全局上下文。包括可用的设备和传输层,进行通信必备的一些资源准备。
- ucp_worker_h:连接,内存等资源的管理和收发完成事件进度推进。
- ucp_listener_h:服务器端监听新连接。
- ucp_ep_h:通信双方收发数据的端点。
- ucp_mem_h:分配或注册的内存句柄。
- ucp_rkey_h:远端内存访问句柄。
UCX对象和底层传输层的映射关系如下:
连接管理
建立连接
- 通信双方在建立连接之前需要创建ucp_context_h和ucp_worker_h对象,服务器端需要从ucp_worker_h对象进一步生成ucp_listener_h对象监听在指定的地址和端口上。
- 客户端从ucp_worker_h对象生成ucp_ep_h对象,生成过程会发送连接请求送到对方的ucp_listener_h对象。
- 服务器端的ucp_listener_h对象接收连接请求并调用预注册的连接回调函数。连接回调函数一般会创建服务器端的ucp_ep_h对象并回复连接响应。
- 客户端收到连接响应后,回复ACK,自此连接建立过程完成,双方可以收发数据消息。
销毁连接
- 连接销毁可以由任意一方发起。发起方调用ucp_ep_close_nb,调用过程会发送断链通知给对方,在等待对方回复断链通知之前,ucp_ep_close_nb返回一个句柄,可供应用后续查询是否断链完成。
- 接收方收到断链通知后,触发预注册的错误回调函数,这个回调函数一般也会调用ucp_ep_close_nb,回复断链通知。
- 发起方收到断链通知后,断链过程完成。
UCP传输协议
UCP层根据消息的大小和配置策略可以为消息选择不同的传输协议。对于小消息,通常eager协议能达到高延迟,而对于大消息,rendezvous协议则有助于达成高吞吐。
eager
- 接收端已经提前注册好了接收内存,接收内存需要大于消息的长度。接收端也注册好了接收回调函数。
- 建立连接后,发送端直接调用ucp_am_send_nbx发送数据给接收方。
- 接收方接收到数据后,ucp_worker_progress会触发接收回调函数被调用,接收数据会被处理,处理完成后会释放数据缓冲区。
rendezvous
- 发送方先发送RTS控制信息,告知发送缓存的地址,长度和密钥。
- 接收方接收到RTS后,准备接收缓存并注册,同时发起RDMA READ将发送缓存的数据搬到接收缓存,搬运完成后,处理接收数据,同时回复ATS控制信息
- 发送方收到RTS后,释放发送缓存。