2 minutes
Linux_iouring
Preface
最近内部经常讨论 io_uring, 这块不是很了解, 特别记录下
回顾io
linux io 模型中主要区分四种类型区分: 同步io 非同步io 和 阻塞io 非阻塞io, 通过不同的组合, 有不同的模型. 如下:
- 同步io + 阻塞io: 用户进程会被阻塞在 recvfrom.
- 同步io + 非阻塞io: recvfrom 会返回 错误表示数据还没有到来, 不会阻塞. O_NONBLOCK 参数
- 同步io + 阻塞io: io多路复用: select/poll/epoll, 虽然读写不会阻塞在recvfrom, 但是会阻塞在select调用.
- 信号驱动: 接收到信号之后需要自己操作
- 异步io: 内核操作完通知. 操作系统提供了 libaio
有人还将 异步io + epoll 进行了实现: http://m.blog.chinaunix.net/uid-16979052-id-3840266.html
io_uring
-
定位: 更高 IOPS 的 async syscall api. (io层的异步api, 主打高性能)
-
特点&主要概念
- 基于ringbuffer 的设计, 提交队列和完成队列只存储索引, SQEs(submission queue entries) 存储请求, 这样提交的请求可以内存不连续
- 用户态和系统态 通过 mmap 共享 提交队列 和 完成队列, 减少地址映射开销
- 在poll模式下, IO提交和收割 可以由 kernel 完成, 不需要系统调用, 系统会启动一个 SQ Poll 的内核线程不断poll (没有请求会睡眠), 处理 sq 和 cq
- 非poll模式下, io_uring_enter 会阻塞, 完成 SQ Poll 线程的任务
- 提供了polling和非polling两种模式, 和底层实现有关, 非polling性能比 libaio 提升不了多少, polling 模式和 SPDK 非常接近. io_uring 有
- 支持 buffered io
相比于之前的aio, 更好的支持了 buffered io, aio 只对 direct io 进行了很好的支持.
aio
不是很推荐, 不赘述, 参考: https://www.man7.org/linux/man-pages/man7/aio.7.html
iocp
windows
spdk
-
定位: 用户态存储应用程序的工具和库
-
特点: 用户态、轮询、异步、无锁 NVMe 驱动,
和iouring (优化系统调用)相比, spdk 是一种bypass kernel的实现方式, 基于 VFIO 在用户态重新实现 NVMe 驱动和协议.
如何体现了这些特点? 用户态: 在用户态重新实现 NVMe 驱动和协议 无锁化: 避免多线程由于对锁的争抢而引入的性能开销 轮询: 避免了传统中断方式由于上下文切换而引入的性能开销, 轮询是否有数据包达到, 没包进入中断 vhost 的 ringbuffer设计: vhost 作为虚拟机存储的后端,以进程的形式在宿主机上运行,通过轮询的方式从共享的 Ring Buffer 中得到虚拟机中的 IO 请求,并进行处理,最后将处理完的数据同样通过 Ring Buffer 的方式通知虚拟机。整个过程不需要锁的保护,没有中断引入的开销,效率极高
补充:
- nvme 是ssd的一套规范, 定义了 主机软件 通过PCIe 和 非易失性内存的方式, 在 SATA 中 host 和 cpu 只有一个通道/队列, 无法充分利用多核, 而在 nvme, 每个核都可以有 65535 (64k) 个队列.
- DPDK: 在传统的 x86 结构中, 网卡收到数据包后需要通过中断方式通知 cpu 处理(cpu拷贝数据到协议栈), 大数据量的时候 中断是个很大的开销. DPDK 模式下, 网卡收到数据包后, 通过零拷贝技术直接将数据存储到内存.
其他术语
QEMU: 硬件虚拟化软件, 处理器、内存、IO 设备的虚拟化, 本质上是一个用户进程. 不依赖kvm. 一个独立的虚拟化解决方案
kvm: linux的一个内核驱动模块,在内核模式和用户模式之外提供了客户模式, 能够加速QEMU. 本身只提供接口.
virtio: qemu模拟io设备效率不高的原因, 通常需要半虚拟化的virtio方式虚拟IO设备
hypervisor: 创建和运行vm的软件. 具体实现由很多, kvm、vSphere、vmware. 有两种模式: 1. 直接运行在硬件上, 2. 基于操作系统之上构建
- https://www.ibm.com/developerworks/cn/linux/l-hypervisor/index.html
- https://www.redhat.com/en/topics/virtualization/what-is-a-hypervisor
hypervisor vs docker: docker 依赖底层操作系统(linux为主,windows/mac需要虚拟机), hypervisor 可以在一台机器上虚拟出多个操作系统.
- https://www.redhat.com/en/topics/containers/containers-vs-vms
NVMe-oF, iSCSI, 和 vhost
参考
- https://cloud.tencent.com/developer/article/1198333 (一文看懂DPDK)
- https://zh.wikipedia.org/wiki/DPDK
- https://zhuanlan.zhihu.com/p/48664113 (QEMU和KVM的关系)
- https://zh.wikipedia.org/wiki/QEMU
- https://zhuanlan.zhihu.com/p/52970477 (使用SPDK技术优化虚拟机本地存储的IO性能)
- https://zhuanlan.zhihu.com/p/71932170 (一篇文章讲清什么是NVMe)
- https://nvmexpress.org/
- https://www.man7.org/linux/man-pages/man7/aio.7.html
- https://kernel.dk/io_uring.pdf
- https://lwn.net/Articles/776703/ (Ringing in a new asynchronous I/O API)
- https://kernelnewbies.org/Linux_5.1
- https://zhuanlan.zhihu.com/p/62682475 (AIO 的新归宿:io_uring)
- https://kernel.taobao.org/2019/06/io_uring-a-new-linux-asynchronous-io-API/
- http://m.blog.chinaunix.net/uid-16979052-id-3840266.html (linux AIO libaio和epoll实现非阻塞模型)
- https://spdk.io/cn/