io_uring 学习总结

这是一篇基于我们刚才的讨论,并结合最新业界动态(截至 2025 年)扩写而成的深度技术博客。你可以直接将其发布在你的技术专栏或团队内部 Wiki 中。


告别 Epoll:Linux io_uring 的“完全体”最佳实践指南

作者:[你的名字] 发布时间:2025年

在 Linux 高性能网络编程领域,epoll 统治了近 20 年。然而,随着 NVMe 存储和 100GbE 网卡的普及,epoll 基于“系统调用+数据拷贝”的模式逐渐触碰到了天花板。

Linux 5.1 引入的 io_uring 被称为“I/O 的革命”。但很多开发者在尝试后发现:“为什么我写的 io_uring demo 并没有比 epoll 快,甚至内存占用还更高?”

本文将深入解构 io_uring 的两种核心模式,并揭示目前业界公认的**“最佳实践组合”**。


1. 认清本质:io_uring 的“双面”人格

理解 io_uring 的第一步,是明白它并非单纯的“异步 IO”,它实际上提供了两种完全不同的编程模型。

模式 A:就绪通知 (Readiness) —— “更好的 epoll”

模式 B:完成通知 (Completion) —— “真正的 io_uring”


2. 陷阱:朴素完成模式的“内存黑洞”

如果你直接在网络编程中使用“完成模式”(即每个连接预先投递一个 recv 请求),你会立刻撞上一堵墙:内存消耗

场景推演

假设你开发一个单机百万连接的网关:

结论:不解决内存管理问题的 io_uring,在网络高并发场景下是不可用的。


3. 最佳实践:io_uring 的“完全体” (The Holy Trinity)

要释放 io_uring 的真正性能,必须组合使用 Linux 5.19+ 引入的一系列高级特性。目前的业界标准做法由以下三个核心要素组成:

要素一:Buffer Ring (Provided Buffers)

要素二:Multishot Receive

要素三:Fixed Files (Direct Descriptors)


4. 业界生态现状与案例验证

关于你提到的活跃度问题,以下是截至 2025 年的最新观察:

  1. Monoio (Rust) [活跃]

    • 状态非常活跃。由字节跳动(ByteDance)开源并维护。
    • 特点:Monoio 是目前严格遵循上述“最佳实践”的代表。它设计为 Thread-per-Core 模型,底层通过 io_uring 的 Provided Buffers 实现了零拷贝。基准测试中,它在吞吐量上经常碾压 Tokio。
    • 勘误:你提到它看起来不活跃,可能是看漏了分支或近期 Commit,实际上它是目前 Rust 生态探索 io_uring 的先锋。
  2. Glommio (Rust) [维护期]

    • 状态维护模式。由 Datadog 开发。
    • 特点:早期理念非常先进(基于 NVMe 的直接 I/O 调度),但随着主要作者的变动,更新频率确实不如 Monoio。它更多聚焦于存储密集型应用。
  3. Netty (Java) [里程碑]

    • 状态Netty 4.2 正式发布
    • 验证:Netty 4.2 终于将 io_uring 传输层从孵化器(Incubator)毕业为正式模块。官方实测在 Linux 6.x 内核上,吞吐量相比 Epoll 提升明显,且 GC 压力更小(得益于 Buffer 管理优化)。
  4. DragonflyDB (C++)

    • 状态:生产级应用。
    • 案例:作为一个 Redis 的高性能替代品,DragonflyDB 宣称比 Redis 快 25 倍,其核心引擎就是基于 io_uring 构建的 Shared-nothing 架构。他们大量使用了 Fixed Files 和 Polling 模式来压榨硬件性能。
  5. Bun (JavaScript Runtime)

    • 案例:Bun 在 Linux 上的高性能 HTTP 服务正是基于 io_uring 实现的,这是它在跑分上吊打 Node.js 的关键原因之一。

5. 总结与建议

如果你要在 2025 年开启一个高性能 I/O 项目:

  1. 不要裸写 io_uring:除非你是内核级开发者,否则细节极其容易出错(如 Memory Ordering 问题)。
  2. 内核版本是关键
    • Kernel 5.10:仅作为最低门槛,许多高级特性不支持。
    • Kernel 5.19+强烈推荐。支持 PBUF_RING
    • Kernel 6.1+:生产环境最佳选择,LTS 版本,修复了大量早期 Bug。
  3. 技术选型
    • Rust: 首选 Monoio(追求极致性能)或 Tokio-uring(追求生态兼容)。
    • C++: 参考 SeastarDragonflyDB 的源码。
    • Java: 直接升级 Netty 4.2

引用与延伸阅读

brpc 中引入 io_uring 的探索与实践
新公司,新环境