Linux高性能异步I/O接口io_uring
由于最近研究高性能的物联网框架,而通信和IO是一个高并发系统最重要的需要考虑的方向。本文主要记录一下对于Linux最新的io_uring的研究和在网络通信方向应用的前景。
io_uring简介
io_uring的引入是从Linux内核5.1版本开始的。这是一个全新设计的,非常精巧的异步I/O框架。Linux系统很早期时间上就有一个异步IO接口,Linux AIO。但是这个接口的设计比较糟糕,使用比较繁琐,扩展也非常麻烦。有很多企业和开发人员试图对Linux AIO进行改进,不过由于最初的设计问题,使得改进极为困难。而且AIO支持直接IO,而不支持缓存IO,这就使得大量需要内核态缓存的应用(包括网络IO)没有办法用到AIO。
io_uring
实现了三个系统调用:
io_uring_setup
, io_uring_enter
和 io_uring_register
。这三个系统调用的功能分别是:
io_uring_setup
用于建立一个io_uring的实体io_uring_enter
用于将SQE(Submission Queue Entry)提交到SQ(Submission Queue)中去。io_uring_register
用于预注册读写文件
io_uring的几个重要概念
- SQ - Submission Queue:提交队列,这是在内核态的一整块连续的内存空间存储的环形队列。用于存放将执行的操作数据项。
- CQ - Completion Queue:完成队列,这是在内核态的一整块连续的内存空间存储的环形队列。用于存放执行完成后的结果。
- SQE - Submission Queue Entry:提交队列项,这是储存在SQ中的数据项。
- CQE - Completion Queue Entry:完成队列项,这是储存在CQ中的数据项。
- Ring - Ring:环:SQ和CQ都是环形队列结构,Ring用来代表一个io_uring的实体。
io_uring的结构示意图
上述示意图大致描绘除了io_uring的结构,SQ和CQ这两个队列通过mmap系统调用建立起内核态和用户态的共享。从而实现了采用io_uring的应用程序,对于IO操作的提交和收割可以不用进行内核态存储区域和用户态的上下文切换,对于大量IO访问的情况下提高了性能。关于什么是内核态,什么是用户态,在下面关于Linux内核会做进一步的介绍。
Linux内核介绍
内核版本的要求
由于众所周知的原因,国内各大开源软件库通常需要