5 个版本 (破坏性更新)
0.5.0 | 2023年2月1日 |
---|---|
0.4.0 | 2022年9月7日 |
0.3.0 | 2022年7月5日 |
0.2.0 | 2022年4月18日 |
0.1.0 | 2022年2月19日 |
#407 in 异步
每月下载量 31 次
405KB
7K SLoC
async-rdma
一个用于编写具有高级抽象和异步 API 的 RDMA 应用程序的框架。
它提供了一些主要组件
-
例如
RdmaBuilder
的用于与 rdma 端点建立连接的工具。 -
包括
read
、write
、send
、receive
的高级 API 用于端点之间的数据传输。 -
包括
alloc_local_mr
、request_remote_mr
、send_mr
、receive_local_mr
、receive_remote_mr
的高级 API 用于 rdma 内存区域管理。 -
包括在 API 背后工作的
agent
和event_listener
框架,用于内存区域管理和执行类似post_send
和poll
的 rdma 请求。
在 ChangeLog 文件中包含了每个版本变更的简要总结。
环境配置
本节面向想要尝试此库的 RDMA 初学者。
如果您已经配置了 RDMA,则可以跳过此部分。
接下来,我们将配置 Ubuntu20.04 虚拟机上的 RDMA 环境。如果您使用的是其他操作系统发行版,请搜索并替换相应的命令。
1. 检查当前内核是否支持 RXE
运行以下命令,如果CONFIG_RDMA_RXE = y
或 m
,则当前操作系统支持RXE。如果不支持,则需要搜索如何重新编译内核以支持RDMA。
cat /boot/config-$(uname -r) | grep RXE
2. 安装依赖项
sudo apt install -y libibverbs1 ibverbs-utils librdmacm1 libibumad3 ibverbs-providers rdma-core libibverbs-dev iproute2 perftest build-essential net-tools git librdmacm-dev rdmacm-utils cmake libprotobuf-dev protobuf-compiler clang curl
3. 配置RDMA netdev
(1) 加载内核驱动
modprobe rdma_rxe
(2) 用户模式RDMA netdev配置。
sudo rdma link add rxe_0 type rxe netdev ens33
rxe_0
是RDMA设备名,您可以将其命名为任何您想要的名称。ens33
是网络设备的名称。网络设备的名称可能因每个虚拟机而异,我们可以通过运行命令"ifconfig"来查看它。
(3) 检查RDMA设备状态
运行以下命令并检查状态是否为ACTIVE
。
rdma link
(4) 测试它
Ib_send_bw是用于测试RDMA SEND
操作带宽的程序。
在终端中运行以下命令。
ib_send_bw -d rxe_0
然后在另一个终端中运行以下命令。
ib_send_bw -d rxe_0 localhost
4. 安装Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source $HOME/.cargo/env
5. 尝试一个示例
git clone https://github.com/datenlord/async-rdma.git
cd async-rdma
cargo run --example rpc
示例
一个简单的示例:客户端请求远程内存区域,并通过rdma write
将数据放入此远程内存区域。最后,客户端send_mr
以使服务器了解此内存区域。服务器receive_local_mr
,然后从该mr获取数据。
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, RdmaBuilder};
use portpicker::pick_unused_port;
use std::{
alloc::Layout,
io::{self, Write},
net::{Ipv4Addr, SocketAddrV4},
time::Duration,
};
async fn client(addr: SocketAddrV4) -> io::Result<()> {
let layout = Layout::new::<[u8; 8]>();
let rdma = RdmaBuilder::default().connect(addr).await?;
// alloc 8 bytes remote memory
let mut rmr = rdma.request_remote_mr(layout).await?;
// alloc 8 bytes local memory
let mut lmr = rdma.alloc_local_mr(layout)?;
// write data into lmr
let _num = lmr.as_mut_slice().write(&[1_u8; 8])?;
// write the second half of the data in lmr to the rmr
rdma.write(&lmr.get(4..8).unwrap(), &mut rmr.get_mut(4..8).unwrap())
.await?;
// send rmr's meta data to the remote end
rdma.send_remote_mr(rmr).await?;
Ok(())
}
#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
let rdma = RdmaBuilder::default().listen(addr).await?;
// receive mr's meta data from client
let lmr = rdma.receive_local_mr().await?;
let data = *lmr.as_slice();
println!("Data written by the client using RDMA WRITE: {:?}", data);
assert_eq!(data, [[0_u8; 4], [1_u8; 4]].concat());
Ok(())
}
#[tokio::main]
async fn main() {
let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
std::thread::spawn(move || server(addr));
tokio::time::sleep(Duration::new(1, 0)).await;
client(addr)
.await
.map_err(|err| println!("{}", err))
.unwrap();
}
获取帮助
首先,看看您的答案是否可以在找到的API文档或设计文档中找到。如果答案不在这里,请打开一个问题并详细描述您的问题。
相关项目
rdma-sys
:RDMA基本库的Rust绑定:libibverbs-dev和librdmacm-dev。
依赖项
~10–25MB
~319K SLoC