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 特性,并设计了一套全新的 I/O 抽象,这不幸地可能导致一些兼容性问题。我们的基准测试 证明,对于我们的用例,Monoio 比其他 Rust 运行时具有更好的性能。
快速入门
要使用 monoio,您需要 rust 1.75。如果您已经安装,请确保它是最新版本。
此外,如果你想使用 io_uring,你必须确保你的内核支持它(5.6+)。并且,memlock 已配置为适当的数值。如果你的内核版本不满足要求,你可以尝试使用 legacy driver 启动,目前支持 Linux 和 macOS(参考此处)。
🚧实验性的 Windows 支持正在路上。
以下是如何使用 Monoio 的基本示例。
/// A echo example.
///
/// Run the example and `nc 127.0.0.1 50002` in another shell.
/// All your input will be echoed out.
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!("listening");
loop {
let incoming = listener.accept().await;
match incoming {
Ok((stream, addr)) => {
println!("accepted a connection from {}", addr);
monoio::spawn(echo(stream));
}
Err(e) => {
println!("accepted connection failed: {}", 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 {
// read
(res, buf) = stream.read(buf).await;
if res? == 0 {
return Ok(());
}
// write all
(res, buf) = stream.write_all(buf).await;
res?;
// clear
buf.clear();
}
}
你可以在本仓库的 examples 中找到更多示例代码。
局限性
- 在 Linux 5.6 或更高版本上,Monoio 可以使用 uring 或 epoll 作为 io 驱动。在较低版本的 Linux 上,它只能以 epoll 模式运行。在 macOS 上,可以使用 kqueue。目前不支持其他平台。
- Monoio 无法解决所有问题。如果工作负载非常不均衡,由于 CPU 核心可能无法被充分利用,它可能会导致性能低于 Tokio。
贡献者
感谢他们的贡献!
关联项目
- local-sync: 一个线程本地通道。
- monoio-tls: Monoio 的 TLS 封装。
- monoio-codec: Monoio 的编解码工具。
HTTP 框架和 RPC 框架正在开发中。
许可证
Monoio 采用 MIT 许可证或 Apache 许可证。
在开发过程中,我们大量参考了 Tokio、Mio、Tokio-uring 和其他相关项目。我们想感谢这些项目的作者。