io_uring==iocp?

linux内核接口调用终于迎来了新的变革,全面支持异步模型。

Windows上有IOCP(IO Completion Port),但是Linux并没有类似的模型。Linux 的epoll只支持网络操作,不支持本地文件操作。linux-aio支持文件操作,但是范围有限。至于那些在应用层实现的异步调用库,比如posix-aio,完全是基于thread-pool来实现的,效率很低。现在io-uringlinux-aio的实现机制进行了推广,这样就可以纳入更多的操作。

性能怎么样?scylladb做了测试,在file io上跟linux-aio差不多

Linux千般好,但是基于社区驱动,缺少顶层设计。就像生物进化一样,很难出现大的变革。不过一旦出现,就可以持续改进。目前io_uring正在呈现井喷式发展,不停的在加入新的OP。

那么如何使用io_uring呢?你当然可以直接使用C库liburing或者类似的Go或者Rust库,但是要把请求和结果进行关联还是比较麻烦的。如果能集成到Go或者Rust的标准运行库里最好了,这样就不用管内核是否支持io_uring,同时保持现有代码不变。

可惜没这么简单,go开发人员认为epoll已经满足net io的需求,而io_uring只是解决file io的问题而已,为此大动干戈是否值得。最主要的是,io_uring貌似更适合于单线程的访问。如果在go routing内部使用必然会导致竞争的问题,访问效率就会下降,因此需要为每个P分配一个ring等等。最大的可能是只对file io使用 io_uring, 而net还是维持netpoll架构。总之,还在观望。

对于Rust,tokio和async-std都没有支持io_uring,不过Ringbahn做了类似实现。

可以想见,近期还会有大量的对io_uring的封装库出现。