”
智汇/ 华云
”
概述
高性能计算是继理论科学和实验科学之后科学探索的第三范式,被广泛应用在高能物理研究、核武器设计、航天航空飞行器设计、国民经济的预测和决策等领域,对国民经济发展和国防建设具有重要的价值。它作为世界高技术领域的战略制高点,已经成为科技进步的重要标志之一,同时也是一个国家科技综合实力的集中体现。
作为信创云计算专家,华云数据已经在政府金融、国防军工、教育医疗、能源电力、交通运输等十几个行业打造了行业标杆案例,客户总量超过30万。在高性能计算方面也部下重局。在华云数据的研发和客户需求调研中发现,随着客户在高性能计算中的求解问题规模的越来越大,对计算能力和存储IO的需求不断增长,并成为计算和存储技术发展最直接的动力。
io_uring是Linux Kernel在v5.1版本引入的一套新异步编程框架,同时支持Buffer IO和Direct IO。io_uring 在设计之初就充分考虑框架自身的高性能和通用性,不仅仅面向传统基于块设备的FS/Block IO领域,对 络异步编程也提供支持,以通用的系统调用提供比肩spdk/dpdk 的性能。
IO演变过程
1、基于fd的阻塞式 I/O:read/write
作为大家最熟悉的读写方式,Linux 内核提供了基于文件描述符的系统调用,这些描述符指向的可能是存储文件(storage file),也可能是network sockets:
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
二者称为阻塞式系统调用(blocking system calls),因为程序调用这些函数时会进入sleep状态,然后被调度出去(让出处理器),直到 I/O 操作完成:
缺点:
随着存储设备越来越快,程序越来越复杂, 阻塞式(blocking)已经这种最简单的方式已经不适用了。
2、非阻塞式 I/O:select/poll/epoll
阻塞式之后,出现了一些新的、非阻塞的系统调用,例如select、poll以及更新的epoll。应用程序在调用这些函数读写时不会阻塞,而是立即返回,返回的是一个已经ready的文件描述符列表。
缺点:只支持network sockets和pipes——epoll甚至连storage files都不支持。
3、线程池方式
对于storage I/O,经典的解决思路是thread pool:主线程将 I/O分发给worker线程,后者代替主线程进行阻塞式读写,主线程不会阻塞。
这种方式的问题是线程上下文切换开销可能非常大,通过性能压测会看到。
4、Direct I/O(数据库软件):绕过 page cache
随后出现了更加灵活和强大的方式:数据库软件(database software)有时并不想使用操作系统的page cache,而是希望打开一个文件后,直接从设备读写这个文件(direct access to the device)。这种方式称为直接访问(direct access)或直接 I/O(direct I/O)。
5、异步IO
随着存储设备越来越快,主线程和worker线性之间的上下文切换开销占比越来越高。现在市场上的一些设备。换个方式描述,更能让我们感受到这种开销:上下文每切换一次,我们就少一次dispatch I/O的机会。因此Linux 2.6 内核引入了异步I/O(asynchronous I/O)接口。
Linux 原生AIO 处理流程:
从上面的流程可以看出,Linux 的异步 IO 操作主要由两个步骤组成:
AIO的缺陷
软件工程中,在现有接口基础上改进,相比新开发一套接口,往往有着更多的优势,然而在过去的数年间,针对上述限制的很多改进努力都未尽如人意。终于,全新的异步IO引擎io_uring就在这样的环境下诞生了。
io_uring原理
io_uring 来自资深内核开发者 Jens Axboe 的想法,他在 Linux I/O stack 领域颇有研究。从最早的patch aio: support for IO polling 可以看出,这项工作始于一个很简单的观察:随着设备越来越快,中断驱动(interrupt-driven)模式效率已经低于轮询模式(polling for completions)。
1、原理及核心数据结构:
每个 io_uring 实例都有两个环形队列(ring),在内核和应用程序之间共享:
这两个队列:
使用方式:
2、 三种工作模式
io_uring 实例可工作在三种模式:
(1)中断驱动模式(interrupt driven)
默认模式。可通过 io_uring_enter 提交 I/O 请求,然后直接检查 CQ 状态判断是否完成。
(2)轮询模式(polled)
Busy-waiting for an I/O completion,而不是通过异步 IRQ(Interrupt Request)接收通知。
这种模式需要文件系统(如果有)和块设备(block device)支持轮询功能。相比中断驱动方式,这种方式延迟更低,但可能会消耗更多 CPU 资源。
目前,只有指定了 O_DIRECT flag 打开的文件描述符,才能使用这种模式。当一个读 或写请求提交给轮询上下文(polled context)之后,应用(application)必须调用 io_uring_enter 来轮询 CQ 队列,判断请求是否已经完成。
对一个io_uring 实例来说,不支持混合使用轮询和非轮询模式。
(3)内核轮询模式(kernel polled)
这种模式中,会创建一个内核线程(kernel thread)来执行SQ 的轮询工作。
使用这种模式的 io_uring 实例,应用无需切到到内核态就能触发(issue)I/O 操作。通过SQ来提交SQE,以及监控CQ的完成状态,应用无需任何系统调用,就能提交和收割 I/O(submit and reap I/Os)。
如果内核线程的空闲时间超过了用户的配置值,它会通知应用,然后进入idle状态。这种情况下,应用必须调用io_uring_enter来唤醒内核线程。如果 I/O 一直很繁忙,内核线性是不会 sleep 的。
3、重要特性
功能对比
1、Synchronous I/O、 Libaio和IO_uring对比
2、io_uring和spdk的对比
性能表现
非polling模式,io_uring相比libaio提升不是很明显;在polling模式下,io_uring能与spdk接近,甚至在queue depth较高时性能更好,完爆libaio。
在queue depth较低时有约7%的差距,但在queue depth较高时基本接近。
以上数据来自来自Jens Axboe的测试:https://lore.kernel.org/linux-block/20190116175003.17880-1-axboe@kernel.dk/
结论:
io_uring在非polling模式下,相比libaio,性能提升不是非常显著。
io_uring在polling模式下,性能提升显著,与spdk接近,在队列深度较高时性能更好。
io_uring在kvm-qemu下的性能表现
1、直接启用io_uring的场景
下面测试结果在一台华云超融合一体机测试,qemu 5.0 已经支持了Asynchronous I/O的io_uring,只需要将虚拟机将驱动改成io_uring。
原理如下:
宿主机环境信息:
虚拟机环境信息
测试参数
[global]
ioengine=libaio
time_based
direct=1
thread
group_reporting
randrepeat=0
norandommap
numjobs=4
ramp_time=10
runtime=600
filename=/dev/sdb
[randwrite-4k-io32]
bs=4k
iodepth=32
rw=randwrite
stonewall
[randread-4k-io32]
bs=4k
iodepth=32
rw=randread
stonewall
测试数据如下:
测试视频:
libaio的4k随机读写
io_uring的4k随机读写
总结:
1)、libaio和io_uring性能比较,io_uring性能提高不明显,没有跨越式的提升。
2)、目前io_uring 的virtio block开发还在持续进行,poll模式等高级功能没有release。很值得期待。具体参见:https://wiki.qemu.org/Features/IOUring
2、io passthrough场景
原理:
直接透传QEMU Block层
测试环境版本信息:
创建虚拟机
aio=io_uring -device virtio-blk-pci,drive=hd1,bootindex=2,io-uring-pt=on
测试结果:
测试数据来自:
https://static.sched.com/hosted_files/kvmforum2020/9c/KVMForum_2020_io_uring_passthrough_Stefano_Garzarella.pdf
总结:
1)、virtio-blk的性能只有裸设备性能的一半左右。
2)、io_uring passthrough的性能和裸设备持平。
3)、缺点需要在guestOS的kernel中打patch。
区支持情况
1、内核支持情况
2、io_uring 区开发现状
当前 io_uring 区开发主要聚焦在以下几个方面。
总结
1、华云数据产品技术中心始终贴近用户,解决用户的实际问题,同时时刻关注业界的先进技术。得益于io_uring的优异的表现,华云数据在此方面投入大量资源。同时我们在RDMA、SPDK、vdpa、DPU、io_uring、eBPF等热门技术也有相关的研究及产品化的丰富经验,同时对 区不断的共享。
2、io_uring 是完全为性能而生的新一代 native async IO 模型,比 libaio 高级不少。通过全新的设计,共享内存,IO 过程不需要系统调用,由内核完成 IO的提交, 以及Polled IO机制,实现了高IOPS。相比kernel bypass,这种原生内核的方式显得友好一些。一定程度上,io_uring代表了Linux kernel block层的未来,至少从中我们可以看出一些block层进化的方向,而且我们看到io_uring也在快速发展,相信未来io_uring会更加的高效、易用,并拥有更加丰富的功能和更强的扩展能力。这让我们充满期待,NVMe的存储时代需要一个属于自己的高速IO引擎。
3、在kvm方面,qemu支持io_uring,在操作和运维方便比spdk的vhost简单很多。虽然支持的还不是很完善,但 区仍然在积极推进。希望这个早日release。
4、国内阿里在io_uring走的比较靠前,阿里有个专门的内核组在做相关的开发。OpenAnolis已经将io_uring纳入,并且在io_uring方面做了很多探索。通过 区的一些文章可以看到,阿里在数据库、web、echo_sever等相关的领域都已经应用了io_uring。
往期推荐 ·
智汇华云 | 华云数据计算团队在内存大页动态分配的探索与实践
智汇华云 | ArSDN之分布式路由及浮动IP简介
智汇华云 | 混合IT下的云管理套件核心技术解析
智汇华云 | kata container virtiofs测试和技术分析
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!