Monoio
一个基于线程每核心模型的 Rust 运行时,支持 io_uring/epoll/kqueue。
设计目标
Monoio 是一个纯粹的 io_uring/epoll/kqueue Rust 异步运行时。部分设计借鉴了 Tokio 和 Tokio-uring。然而,与 Tokio-uring 不同,Monoio 不依赖于其他运行时,因此更加高效。
此外,Monoio 设计时考虑了线程每核心模型。用户无需担心任务是否 Send
或 Sync
,因为线程本地存储可以安全使用。换句话说,与 Tokio 等工作窃取运行时不同,数据在 await 点不会逃逸到其他线程。这是因为对于某些用例,特别是本运行时针对的用例,不需要使任务在线程间可调度。例如,如果我们要编写一个类似 NGINX 的负载均衡器,我们会采用线程每核心的方式编写。线程本地数据不需要在线程间共享,因此不需要实现 Sync
和 Send
。
正如您可能猜到的,这个运行时主要针对服务器,其操作主要受网络套接字的 I/O 限制,因此使用原生异步 I/O API 可以最大化服务器的吞吐量。为了使 Monoio 尽可能高效,我们启用了一些不稳定的 Rust 特性,并设计了全新的 IO 抽象,这可能会导致一些兼容性问题。我们的基准测试证明,对于我们的用例,Monoio 比其他 Rust 运行时具有更好的性能。
快速开始
要使用 Monoio,您需要 rust 1.75。如果您已经安装了,请确保它是最新版本。
此外,如果您想使用 io_uring,必须确保您的内核支持它(5.6+)。并且,memlock 配置为适当的数值。如果您的内核版本不满足要求,可以尝试使用旧版驱动程序启动,目前支持 Linux 和 macOS(参考这里)。
🚧Windows 支持正在实验中。
以下是使用 Monoio 的基本示例。
/// 一个回显示例。
///
/// 运行示例并在另一个终端中执行 `nc 127.0.0.1 50002`。
/// 您的所有输入都将被回显。
use monoio::io::{AsyncReadRent, AsyncWriteRentExt};
use monoio::net::{TcpListener, TcpStream};
#[monoio::main]
async fn main() {
let listener = TcpListener::bind("127.0.0.1:50002").unwrap();
println!("正在监听");
loop {
let incoming = listener.accept().await;
match incoming {
Ok((stream, addr)) => {
println!("接受来自 {} 的连接", addr);
monoio::spawn(echo(stream));
}
Err(e) => {
println!("接受连接失败: {}", e);
return;
}
}
}
}
async fn echo(mut stream: TcpStream) -> std::io::Result<()> {
let mut buf: Vec<u8> = Vec::with_capacity(8 * 1024);
let mut res;
loop {
// 读取
(res, buf) = stream.read(buf).await;
if res? == 0 {
return Ok(());
}
// 全部写入
(res, buf) = stream.write_all(buf).await;
res?;
// 清空
buf.clear();
}
}
您可以在本仓库的 examples
目录中找到更多示例代码。
局限性
- 在 Linux 5.6 或更新版本上,Monoio 可以使用 uring 或 epoll 作为 io 驱动。在较低版本的 Linux 上,它只能在 epoll 模式下运行。在 macOS 上,可以使用 kqueue。目前不支持其他平台。
- Monoio 无法解决所有问题。如果工作负载非常不平衡,可能会导致性能下降,比 Tokio 更糟,因为 CPU 核心可能无法充分利用。
贡献者
感谢他们的贡献!
社区
Monoio 是 CloudWeGo 的子项目。我们致力于构建云原生生态系统。
相关项目
- local-sync:线程本地通道。
- monoio-tls:Monoio 的 TLS 包装器。
- monoio-codec:Monoio 的编解码器工具。
HTTP 框架和 RPC 框架正在开发中。
许可证
Monoio 采用 MIT 许可证或 Apache 许可证。
在开发过程中,我们参考了很多来自 Tokio、Mio、Tokio-uring 和其他相关项目的内容。我们要感谢这些项目的作者。