赞
踩
此文来自于AndresFreund,PG社区资深开发,探讨IO对于PG方面的问题。此翻译和文字来自于视频,因为部分英文听的比较费劲,所以可能有失误的地方,尽请见谅。
最近问问题的同学挺多的,也有问有没有群的,实在是忙没有建群,所以问的人多了,想想还是建一个群,但本人写文章不懒,其他的比较懒,因为问POLARDB的问题的多,所以建立了一个POLARDB和PG,MYSQL,MOGNODB,REDIS,数据库 以及文章问题的讨论群。希望能帮助自己也帮助大家共同提高,要进群的,可以添加微信 liuaustin3 ,来申请加群.
_____________________________________________________________________
正文
接上期,我们说到一个尴尬的地方,就是POSTGRESQL在IO 设计方面的一些问题并不是很好,原因主要提到了人力资源与开发POSTGRESQL 内核的人员过少的问题。这里的10个人,也不是FULL TIME 的,一部分是PART TIME 的工作人员。
当然还有一个原因是要改变这个目前的情况并不容易,我们有四个部分关于bankend 的部分需要进行修改,但实际上我们也需要权衡,目前并没有太大的动力让我们在重新看这部分内容。还有一个原因是IO 非常依赖与平台,基于我的经验,LINUX 的部署以我的经验,比如linux的实现实际上并没有使用适当的io它是使用线程IO实现的,它充满了数据丢失类型的bug,所以它基本上只是实现了一些简单东西,他使用一些postix兼容性,所以即使只是使用简单的IO API也不一定能做的让他变得更好。
另外还有一些原因,就是在使用POSTGRESQL的时候并没有懂POSTGRES的DBA或者一些开发者,将SHAREBUFFER调整到适合的SIZE,同时还有一些设置将POSTGRES在一个硬件中安装了多个POSTGRES,那么在这样的情况下,实际上,还不如让内核管理来决定哪个应用程序可以使用缓存和IO更加合适。同时我们不直接控制IO ,或者操控IO ,而是通过平台来进行调用,事实是,我们中一些最好的社区已经陷入了,或者说某一些采用了一些务实的决定,如我们的 IO 部分避免浪费时间,而使用了基础产品提供商的解决方案。
但是我们为什么要改变,为什么需要改变,主要还是硬件变化了,以及POSTGRESQL的项目变得越来越大,但说到底还是因为我们的存储变化了,与我们传统的存储设备不一样了。
首先我们看NVME,可能你的笔记本上就有NVME,通过SSD 存储来实现NVME典型通过pcie来访问,或者通过网络通道来访问。这与我们之前的传统的存储设备的协议有很大的不同。他允许通过多路控制来实现数据的读取和写入而不需要cache的接入,每一个IO都需要多次的非缓存访问和非缓存的内存访问,这就像一个成百上千的循环,所以每一个IO的实际上并不便宜,这里的问题不在于磁盘设备越来越慢,而是越来越快,这就导致一个问题更为突出了,曾经是一个大的问题,而在NVMe 设备中更为直接的数据访问或直接使用内核来缓存页面变得更快,因为通过kernel page cache 会产生更多的延迟,进程之间的调度问题让更快的硬件本身没有优势。相比较过去的20年,在内存方面的进步是非常小的,也就是1.5 到两倍的,少有太大的改进,
问题在于利用率的问题,之前SATA等磁盘最多是500MB的带宽,而现在的的存储系统的带宽可以达到3-7,所以使用kernel page cache 这里的如果使用kernel page cache 带宽,copyingdata数据来自于kernel cache 在到应用的内存是一个非常严重的问题,这里的问题主要发生在服务器系列的系统,而不是你的桌面电脑或笔记本。这里一个数据交换进程就可以达到8-9G 每秒,所以单一的进程来copydata本身就是一种对硬件资源的浪费,在LINUX 系统中page cache不能完全利用这样的速度,内存的分配和使用需要更快的速度。
NVMe 可以有更多的IO 并发的承载力,可以在同一个时刻服务于多个进程,云的网络存储与我们传统的存储也有非常大的不同。这里提到的是,他们的延迟比本地的磁盘系统要高,部分系统有0.3毫秒的延迟,这个数据是来自于去年年中的数据,不同的云厂商的延迟在0.1 - 0.4毫秒,同时这里有便宜的和贵的的云厂商的产品,当然这比传统的数据存储也要快,他们是在10-16毫秒,但最不同的是并发的特性,这个是传统的系统没有的,基于云上的POSTGRES 最大的问题是wal 日志单线程的与硬件系统多线程IO之间的不均衡的问题,所以我们必须要进行转变,来解决问题。
所以我们要转变方向,在POSTGRES,我是在2019年开始这个工作的,主要的动机也来源于在这段时间Linux引入了AIO,异步的IO 这非常吸引我,也是一个主要的原因,支持 buffer io 异步的工作,这对我们的一些工作有很大的帮助,尤其在使用POSTGRESQL中并不能调整他到最优的状态的情况下,也没有什么自动调整的功能等等。同时在我工作期间,有两个同时加入到我的工作给我很大的帮助,Tomas munro 做了大量的工作,Melanie Plageman做了数据预取的工作。
这里有一些关于POSTGRES用于设计方面的内容,第一个就是 process model,大量的AIO 使用多进程不发生问题是一件不容易的事情,很明显我们的工作中导向是线程,在POSTGRES中使用,我个人当然不光是我本人,一大部分人都是这样认为的,因为一个进程在异步IO中启动,然后在锁上被阻塞,锁的持有者也在等待第一个进程的IO启动完成,此时没有任何事情可以继续。进程的另一个问题我们也不希望设计一个内部进程之间的联系和切换的工作在IO 这个部分。但问题是不是每个平台和操作系统都支持,和认为这个是必须的,但我们也不会介入其中。
内部的process 交换是非常昂贵的,对比线程的模式,因为上下文的交换是需要memory mapping的改变是在不同的进程之间进行切换的。TLB等需要更改,或者至少存在争用.
提问者:(声音很含糊,我真的听不清他在说什么)
回答:我没有做任何事情,我们也没有做任何线程有关的事情,因为这就是一个很大的项目对于我们来说。另外一件事是我们需要去处理潜在的问题。另外我们不希望AIO的复杂性在POSTGRES中蔓延到不同的地方,如我们不希望在VACUUM中通过AIO来进行顺序扫描位图索引,因为那样将会变得很难进行实现和维护,尤其对于我们现在开发的TEAM的人员配置。
基于以上的这些,在目前这点时间,我不能在深入到一些细节了,但是我可以确定的是我们避免了死锁的问题,正如我上面提到的,IO 也有很多类型,我之前AIO 本身并不是AIO模块本身,AIO本身也不会到达sharedbuffer,如wal 不进入share buffers 的部分我们会使用AIO,AIO层可以做的是在将IO提交给硬件层或系统层之前进行一些优化,如果他提交了用于不同共享缓冲去的IO,我们可以将这些IO 聚合成合并成为一个IO,虽然对于硬件我们是强依赖的,但是我们在这部分代码上的修改有了很多的改进,其中一些已经提交了,一些仍在在路上,等待着后续的去补丁。
这里与AIO交互的是通过流式读接口,IO用户提供一个回调,一部分还是基于排队的原则,另一部分进行了代码的修改和改善,但根本还是要取决于你的硬件的能力。
目前我们有四个不同的AIO 在后端。通过PATCH 和补丁的方法,后面我们会继续使用这样的方式,这样的好处是在使用AIO的情况下我们根本不用中断处理,内核部分可以通过拉取队列的方式来进行提交这样的好处是无需进行系统的调用。
另外说说我们需要对IO的这部分修改的必要性在哪里,实际上我们是可以不使用POSTGRES来去处理IO部分的代码,但是POSTGRES是一个多平台的数据库产品,那么不是所有的平台都有标准的AIO,即使他们有,但是也不可能每个平台的AIO部分是统一的标准的,那么我们进行移植这些代码的成本就非常高,我们使用POSIXIO主要的原因是大部分系统支持这个方式,这里有一些丑陋的代码与backend进程有关,同时我们还对进程中的IOCP 在windows 中的部分进行了处理,对于我们来说基于WINDOWS的部分有更多的工作要做,主要也是我们都不是WINDOWS的专家,所以很多部分都是进行远程开发的模式进行的,所以导致WINDOWS 部分的开发延迟。
DIRECTI/O AND CONCURRENTI/O(注:dio=directio,cio = current io)
我们在相关的一些PG 的子系统中已经使用了AIO,如灾难恢复中考虑性能的问题已经不再使用DIO,其中有一部分正在PATCH阶段,最近使用的是posix f advisor 等等,这里重要的部分是在做recovery 操作中是需要读wal 的头部数据来进行数据的重放,之前我们的wal产生的速度很快,在我们使用同步的IO ,而恢复的过程中需要读 wal 然后读所有的buffers ,这里如果使用direct io将是极其缓慢的。我这里有很多案例,如产生5分钟的WAL 数据通过DIO进行回放是非常慢的,要几个小时,所以也就很容易想到在开发中很容易就碰到系统crash的情况,尤其在新的代码合并的情况下。
以上是第二部是本次视频的3分之2部分。
待......
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。