2026-03-14 · linux / io_uring
【io_uring 系列】io_uring 多线程编程模式:从线程安全到架构选型
系统梳理 io_uring 的线程安全模型与四种主流多线程架构模式(Thread-per-Ring、Shared Ring、Submit/Reap 分离、SQPOLL),包含完整的多线程 Echo Server 实战、NUMA 优化、性能对比与生产避坑指南。
在现代高性能计算与大规模分布式系统的演进过程中,输入/输出(I/O)子系统的效率始终是制约系统吞吐量与响应延迟的核心瓶颈。随着硬件性能的飞速发展,特别是 NVMe 存储设备和百兆比特以太网的普及,传统 I/O 模型的局限性日益凸显。
在这一背景下,io_uring 及其配套库 liburing 的出现,不仅是对原有异步 I/O 接口的重构,更是 Linux 内核 I/O 范例的一次深刻革命。
传统的高并发网络编程主要依赖 Reactor 模式(如 epoll)。这种模式是”就绪驱动”的:内核告知应用”数据已到达,你可以读了”,应用随后发起同步调用进行数据搬运。这导致了频繁的系统调用边界跨越和内核/用户空间的上下文切换。
io_uring 引入了 Proactor 模式,实现了真正的”完成驱动”:应用直接下发”请把数据读到这个缓冲区,完成后告诉我”的指令,内核在后台异步完成读操作及数据搬运,最后将结果推入完成队列。
io_uring 的核心是两个基于共享内存的环形队列:
这种双环结构利用内存屏障和原子操作实现了锁无关(Lockless)同步,规避了内核锁竞争开销。
为了进一步压榨性能,io_uring 支持资源提前注册:
io_uring_register_buffers()
提前钉住用户内存页,允许内核设备通过 DMA
直接访问,跳过了每请求一次的虚拟地址映射和内存拷贝。针对极端性能需求,SQPOLL 模式允许专门的内核线程 sqthread 持续轮询提交队列。
sq_thread_idle
时间内无请求,线程会进入休眠,应用需通过
io_uring_enter()
唤醒,从而兼顾了资源利用率。原本的 io_uring 遵循”一请一回”逻辑。现代内核强化了 Multishot 功能:
IORING_CQE_F_MORE
标志,应用可以极低开销处理高频小包。在 Linux 6.15 中,io_uring 实现了网络接收路径的全零拷贝。其依赖于:
实测表明,在 400 Gb/s 环境下,该技术能使内存带宽占用减半,吞吐量提升至 epoll 的 2.5 倍。
延伸阅读:零拷贝并非银弹——关于 sendfile/splice/io_uring 零拷贝路径的隐藏成本与适用边界,详见 Zero Copy 的脏真相:它什么时候反而更慢。
| 项目 | 使用方式 | 取得成果 (2024-2025 数据) |
|---|---|---|
| PostgreSQL 18 | 取代传统辅助线程池,主进程直连 SQ | 事务率从 1.65 万 tx/s 提升至 54.65 万 tx/s |
| RocksDB | 集成 C++ 协程,实现两阶段异步 Seek | 随机读吞吐量提升 2-5 倍,I/O 延迟降低 50-80% |
| Envoy Proxy | 实验性 TCP 监听与连接支持 | 吞吐量增加 10%,延迟降低 10% |
| Ceph BlueStore | 异步块读写后端 | 4KB 随机写 IOPS 提升 18%,长尾延迟下降 80% |
| QEMU 10.2 | 主循环全面基于 io_uring 驱动 | 虚拟机磁盘 I/O 接近物理 NVMe 极限 |
研究发现,io_uring 并非在所有场景下都优于 epoll:
io_uring 允许不经过传统系统调用(如 read/write)执行操作,这使得许多基于系统调用挂钩(Hooking)的安全工具(如 Falco, Defender)产生”盲点”。
Curing Rootkit:研究人员已证明利用 io_uring 构建完全不触发传统审计的后门是可行的。
tracepoint:io_uring:io_uring_submit_sqe
等内核探针,开发者可以实时观测请求的流向和内核线程的活跃状态。IORING_OP_MSG_RING
实现跨核心、跨设备的高效指令编排。liburing 与 io_uring 的组合不仅提升了性能,更重塑了 Linux 下高性能软件的开发思维。虽然安全风险和编程复杂度仍是门槛,但在 2025 年后的万物互联与 AI 计算时代,深度驾驭这一异步范式已成为系统级架构师的必修课。
下一篇: 02-vs-epoll-performance.md - io_uring vs epoll 性能与架构对比
把当前热点继续串成多页阅读,而不是停在单篇消费。
2026-03-14 · linux / io_uring
系统梳理 io_uring 的线程安全模型与四种主流多线程架构模式(Thread-per-Ring、Shared Ring、Submit/Reap 分离、SQPOLL),包含完整的多线程 Echo Server 实战、NUMA 优化、性能对比与生产避坑指南。
2025-11-30 · linux / io_uring
全方位对比 io_uring 与 epoll:从系统调用开销、内存管理到编程模型,分析 io_uring 在高性能 I/O 场景中的优势与局限。
2025-11-30 · linux / io_uring
手把手教你使用 liburing 编写第一个 io_uring 程序。详解 io_uring_queue_init, io_uring_submit 等核心 API 的使用流程。
2025-11-30 · linux / io_uring
深入网络编程,实现一个异步 TCP 服务器。学习如何使用 user_data 管理连接上下文,处理 Accept, Read, Write 链式调用。
在现代高性能计算与大规模分布式系统的演进过程中,输入/输出(I/O)子系统的效率始终是制约系统吞吐量与响应延迟的核心瓶颈。随着硬件性能的飞速发展,特别是 NVMe 存储设备和百兆比特以太网的普及,传统 I/O 模型的局限性日益凸显。
在这一背景下,io_uring 及其配套库 liburing 的出现,不仅是对原有异步 I/O 接口的重构,更是 Linux 内核 I/O 范例的一次深刻革命。
传统的高并发网络编程主要依赖 Reactor 模式(如 epoll)。这种模式是”就绪驱动”的:内核告知应用”数据已到达,你可以读了”,应用随后发起同步调用进行数据搬运。这导致了频繁的系统调用边界跨越和内核/用户空间的上下文切换。
io_uring 引入了 Proactor 模式,实现了真正的”完成驱动”:应用直接下发”请把数据读到这个缓冲区,完成后告诉我”的指令,内核在后台异步完成读操作及数据搬运,最后将结果推入完成队列。
io_uring 的核心是两个基于共享内存的环形队列:
这种双环结构利用内存屏障和原子操作实现了锁无关(Lockless)同步,规避了内核锁竞争开销。
为了进一步压榨性能,io_uring 支持资源提前注册:
io_uring_register_buffers()
提前钉住用户内存页,允许内核设备通过 DMA
直接访问,跳过了每请求一次的虚拟地址映射和内存拷贝。针对极端性能需求,SQPOLL 模式允许专门的内核线程 sqthread 持续轮询提交队列。
sq_thread_idle
时间内无请求,线程会进入休眠,应用需通过
io_uring_enter()
唤醒,从而兼顾了资源利用率。原本的 io_uring 遵循”一请一回”逻辑。现代内核强化了 Multishot 功能:
IORING_CQE_F_MORE
标志,应用可以极低开销处理高频小包。在 Linux 6.15 中,io_uring 实现了网络接收路径的全零拷贝。其依赖于:
实测表明,在 400 Gb/s 环境下,该技术能使内存带宽占用减半,吞吐量提升至 epoll 的 2.5 倍。
延伸阅读:零拷贝并非银弹——关于 sendfile/splice/io_uring 零拷贝路径的隐藏成本与适用边界,详见 Zero Copy 的脏真相:它什么时候反而更慢。
| 项目 | 使用方式 | 取得成果 (2024-2025 数据) |
|---|---|---|
| PostgreSQL 18 | 取代传统辅助线程池,主进程直连 SQ | 事务率从 1.65 万 tx/s 提升至 54.65 万 tx/s |
| RocksDB | 集成 C++ 协程,实现两阶段异步 Seek | 随机读吞吐量提升 2-5 倍,I/O 延迟降低 50-80% |
| Envoy Proxy | 实验性 TCP 监听与连接支持 | 吞吐量增加 10%,延迟降低 10% |
| Ceph BlueStore | 异步块读写后端 | 4KB 随机写 IOPS 提升 18%,长尾延迟下降 80% |
| QEMU 10.2 | 主循环全面基于 io_uring 驱动 | 虚拟机磁盘 I/O 接近物理 NVMe 极限 |
研究发现,io_uring 并非在所有场景下都优于 epoll:
io_uring 允许不经过传统系统调用(如 read/write)执行操作,这使得许多基于系统调用挂钩(Hooking)的安全工具(如 Falco, Defender)产生”盲点”。
Curing Rootkit:研究人员已证明利用 io_uring 构建完全不触发传统审计的后门是可行的。
tracepoint:io_uring:io_uring_submit_sqe
等内核探针,开发者可以实时观测请求的流向和内核线程的活跃状态。IORING_OP_MSG_RING
实现跨核心、跨设备的高效指令编排。liburing 与 io_uring 的组合不仅提升了性能,更重塑了 Linux 下高性能软件的开发思维。虽然安全风险和编程复杂度仍是门槛,但在 2025 年后的万物互联与 AI 计算时代,深度驾驭这一异步范式已成为系统级架构师的必修课。
下一篇: 02-vs-epoll-performance.md - io_uring vs epoll 性能与架构对比
把当前热点继续串成多页阅读,而不是停在单篇消费。
2026-03-14 · linux / io_uring
系统梳理 io_uring 的线程安全模型与四种主流多线程架构模式(Thread-per-Ring、Shared Ring、Submit/Reap 分离、SQPOLL),包含完整的多线程 Echo Server 实战、NUMA 优化、性能对比与生产避坑指南。
2025-11-30 · linux / io_uring
全方位对比 io_uring 与 epoll:从系统调用开销、内存管理到编程模型,分析 io_uring 在高性能 I/O 场景中的优势与局限。
2025-11-30 · linux / io_uring
手把手教你使用 liburing 编写第一个 io_uring 程序。详解 io_uring_queue_init, io_uring_submit 等核心 API 的使用流程。
2025-11-30 · linux / io_uring
深入网络编程,实现一个异步 TCP 服务器。学习如何使用 user_data 管理连接上下文,处理 Accept, Read, Write 链式调用。