内核态AIO VS 用户态AIO
发表于 2026/04/30
0
作者|黎炳材
背景介绍
在当今高并发、IO 密集型的系统架构中,异步 IO(AIO)一直是提升性能的关键技术。然而,关于“AIO 应该放在哪里实现”的讨论,业界存在着明显的分水岭:内核态 AIO 与 用户态 AIO。内核态 AIO 依托于操作系统提供的原生接口(如 Linux 的 io_uring 或传统的 libaio),理论上能减少系统调用开销,实现真正的异步语义;而用户态 AIO 则通过在应用层模拟异步行为(如基于事件循环 + 线程池),虽然绕过了内核调度的某些局限,但可能引入额外的内存复制和上下文切换。理解这两者的本质区别,是构建高性能存储系统或网络服务的基石。
用户态AIO
普遍使用的是POSIX AIO。是一个用户级实现,在多个线程中执行正常的阻塞 I/O,从而给人一种 I/O 异步的错觉。这样做的主要原因是:
1.它适用于任何文件系统
2.它基本上可以在任何操作系统上运行(记住GNU的LIBC是便携的)
3.它适用于启用缓冲(即未设置O_DIRECT标志)的文件
主要缺点是队列深度(即实际可完成的未完成操作数量)受限于你选择的线程数,这也意味着一个磁盘上的慢操作可能会阻碍到另一个磁盘的操作。这也会影响内核和磁盘调度器能看到的输入/操作系统(或数量)。
内核态AIO
普遍使用的是LIBAIO,是内核对异步I/O操作的支持,其中IO请求实际上被排队在内核中,按你所用的磁盘调度器排序,其中部分请求会以理想顺序转发到实际磁盘,作为异步操作(使用TCQ或NCQ)。
模拟测试
接下来我们采用NVME硬盘、测试工具FIO可进行实测模拟。分别采用不同的队列深度和线程数对POSIX AIO和LIBAIO进行测试,结果如预期一致,用户态 POSIX AIO性能与线程数强相关。这说明了业务如果使用了用户态AIO,需要特别关注他的IO线程数量。
IO模式 | 队列深度 | 线程数 | 性能比例 | 测试命令 |
LIBAIO | 1 | 20 | 100% | fio -name=rand_read |
LIBAIO | 20 | 1 | 100% | fio -name=rand_read |
POSIXAIO | 1 | 20 | 100% | fio -name=rand_read |
POSIXAIO | 20 | 1 | 45% | fio -name=rand_read |
开源软件trafficserver业务测试
问题背景:业务性能未达到硬盘性能瓶颈,怀疑业务配置有误。
最后在官方文档中查找到了相关资料,发现该软件默认使用的是线程AIO即用户态AIO。业务性能与AIO数量强相关,通过扩大IO线程数量后性能提升36%



