io_uring

Last edited
Last updated July 9, 2023
Pages
Tags
Linux

io_uring 背景

AIO现状

系统调用比较多,比较难用
不够异步,没有解决所有的阻塞点,例如内核中的 Block 层的 request 就可能导致阻塞
仅支持 Direct IO(应该是指 unbuffered IO,文件 IO)
IO 请求元数据开销较大,如果请求只有几百字节,浪费很大
IOPOLL 支持不好(即轮询的方式)
现在硬件起来了,软件成为瓶颈

io_uring 优势

简单强大的系统调用,提高三个系统调用,liburing 用户动态库编程友好(io_uring_setupio_uring_enter, io_uring_register
通用型强:提供内核同一的异步编程框架,既支持传统 IO (buffer IO + direct IO),也支持 epoll 型编程
特性丰富:支持非常多的高级特性,可想象的空间丰富
高性能:IO 请求 overhead 小

aio - io_uring - spdk 性能对比

io_uring 基本和 spdk 几百持平

io_uring 架构机器重要特性

io_uring 整体架构

notion image
两 ring 一线程(ring 即环形队列)
两组 ring buffer,一组用于存放 sqe,一组用于存放 cqe,其中 sqe 描述 io 请求,cqe 描述 io 完成(这两个 ring,是通过 mmap 实现用户态和内核态共享的)
io_uring_enter(2) 即可以完成提交 io 请求,也可以 reap 完成的 io 请求

io_uring 重要特性

  • IORING_SETUP_SQPOLL:创建一个内核线程进行 sqe 的处理(io提交),几乎完全清除用户态内核上下文切换,并真正将 IO 裸机 offload,实现业务逻辑与 IO 逻辑的分离
  • IORING_SETUP_IOPOLL:配合 blk-mq 多类型硬件队列映射机制,利用此特性,内核 IO 协议栈开始真正完全支持 iopoll
  • IORING_FEAT_FAST_POLL:网络编程新利器,向 epoll 等传统基于事件驱动的网络编程模型发起挑战,向用户态提供真正的异步编程 API

io_uring 优化工作

汇合 io_uring 到 Anoglis OS 8 内核,并在使用过程中进行相对应的优化,相关优化都已贡献到上游社区。截止目前累计贡献约 60 个补丁。涵盖:
  • 特性支持和重构:如扩展 sqpoll,实现 sqpoll percpu 功能
  • 性能优化:利用自研 perf-test-for-io_uring 测试套件优化多个性能瓶颈
  • Bug Fix:利用 Abaci Fuzz Platform 发现并解决大量竞争、死锁等 BUG

io_uring 应用实践

图数据库引擎

业务特点:
  • Direct IO
  • 4KB Size
  • 容器环境
  • 混部场景
优化策略:
  • 开启 sqpoll 特性
  • 开启 iopoll 特性
  • 使用 register files 特性
  • 更高精度的 sqthread 工作/睡眠机制
  • 业务上下文参与提交 IO
  • 提高 sqthread 的优先级
  • 优化容器 CPU 资源统计
notion image

Netty

Netty 目前已支持 io_uring,利用 io_uring 的 IORING_FEAT_FAST_POLL 特性:
notion image
notion image
notion image