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

参考