PostgreSQL 18 引入异步 I/O:大幅提升云环境下的磁盘读取性能
本周,随着Postgres 18 Beta 1版本的发布,多年的努力和架构重大变革终于显现出成果——异步输入输出(AIO)。尽管这些功能仍在积极开发中,但它们代表了Postgres处理I/O方式的根本改变,有望在云环境中显著提升性能,尤其是在高延迟成为瓶颈的情况下。 Postgres历来采用同步I/O模型,这意味着每个读取请求都是一个阻塞系统调用。数据库必须暂停并等待操作系统返回数据后才能继续执行,导致了不必要的等待,尤其在云环境中存储往往是通过网络连接的(如Amazon EBS),I/O延迟可达1毫秒以上。 为了克服这一瓶颈,异步I/O允许程序并发发出多个读取请求,而不需要等待之前的读取完成。这种异步程序流中,I/O请求被安排读入内存位置,程序则等待这些读取完成,从而替代了逐一发出读取指令的方式。 Postgres 17中的读取流API为实现异步I/O奠定了基础,将读取操作标准化,简化了posix_fadvise()的使用,以请求操作系统预先加载数据。但是,这个机制仅提示内核将数据加载到OS页面缓存中,而不是Postgres自身的共享缓冲区,且内核读取行为并不总是稳定。 即将发布的Postgres 18通过真正的异步读取消除了这一间接环节。数据库直接将数据读取到共享缓冲区,绕过内核级别的启发式算法,实现了更可预测、更高吞吐量的I/O行为。 为了控制异步I/O的机制,Postgres 18引入了一个新的配置参数:io_method。这个设置决定了读取操作的幕后分发方式,包括是否同步处理、委派给I/O工作进程还是直接通过io_uring提交给内核。目前,默认设置为worker模式(截至Beta 1版本): io_method = sync:保持同步、阻塞式读取,使用posix_fadvise()实现读取预提。 io_method = worker:利用专用的后台I/O工作进程独立于查询执行来检索数据。主进程将读取请求排队,这些工作进程与Linux内核交互并获取数据到共享缓冲区,不阻塞主进程。 io_method = io_uring:一种仅限Linux的高效I/O接口,通过在Postgres与内核之间建立共享环形缓冲区,最小化系统调用开销。这是最高效的选项,完全消除了I/O工作进程的需求,但仅适用于较新的Linux内核和兼容io_uring支持的文件系统配置。 目前,Postgres 18的异步I/O仅支持顺序扫描、位图堆扫描和维护操作(如VACUUM)。 异步I/O的实际表现 异步I/O在云环境中尤其是网络连接存储如AWS EBS卷上,带来了最明显的优势。在这些环境中,单个磁盘读取通常需要几毫秒,增加了显著的延迟。传统的同步I/O使得每个读取操作都会阻塞查询执行,导致CPU闲置和吞吐量下降。相比之下,异步I/O允许Postgres并发发出多个读取请求,继续处理其他任务,从而减少查询延迟,提高I/O带宽和CPU周期的利用率。 基准测试 我们在AWS c7i.8xlarge实例(32 vCPU,64 GB RAM)上测试了Postgres 17与18使用不同io_method设置的性能差异,使用的Postgres卷为100GB的io2 EBS,配额IOPS为20,000。测试表大小为3.5GB,并清空了OS页面缓存以模拟冷缓存情况。 结果显示,在冷缓存情况下,无论是worker模式还是io_uring模式,Postgres 18的读取性能比传统同步方法提高了2-3倍。worker模式在热缓存情况下也有轻微优势,但io_uring由于更低的系统调用开销和减少了进程协调,始终在冷缓存测试中表现最佳,因此推荐使用io_uring模式以最大化I/O性能。 配置优化 effective_io_concurrency参数在Postgres 18中变得更加有用,特别是与异步io_method(如worker或io_uring)结合使用时。现在,它直接控制Postgres内部发出的异步提前读取请求数量。最优值需要根据实际的I/O子系统进行基准测试,例如,对于支持高并发的高延迟云环境(如具有高配额IOPS的AWS EBS),更高的值可能更为有利。 监控与调试 异步I/O改变了后端等待行为,在使用io_method = worker时,后端进程会将读取请求委托给单独的I/O工作进程,因此后端可能显示为空闲或出现新IO / AioIoCompletion等待事件,而I/O工作进程则显示实际的I/O等待事件。当使用io_method = io_ering时,读取操作直接提交给内核并异步完成,后端过程不会阻塞在传统I/O系统调用上,即使I/O操作正在进行中,这一点也无法从Postgres外部观察到。 为了帮助调试正在飞行中的I/O请求,Postgres 18引入了新的pg_aios视图,可以显示Postgres的内部状态,即使在使用io_uring时也是如此。理解这些行为变化对于优化Postgres 18中的I/O性能至关重要,因为异步I/O会隐藏I/O开销在查询计划中。 结论 Postgres 18的发布标志着其I/O处理方式的重大演进。虽然当前仅限于读取操作,异步I/O已经为高延迟云环境中的性能大幅提升打开了大门。工程团队需要调整他们的监控策略,理解新的定时和等待事件语义,并重新审视之前影响有限的调优参数,如effective_io_concurrency。未来版本(19及之后)可能会带来异步写支持,进一步减少现代工作负载中的I/O瓶颈,甚至启用直接I/O的生产使用。 行业专家对Postgres 18的异步I/O功能持乐观态度,认为这是一次重要的技术突破。Postgres是一个开源关系型数据库管理系统,以其稳定性和功能强大著称,广泛应用于各类企业和互联网应用。此次更新将进一步增强其在云环境中的竞争力,提升大规模数据处理的能力。
