说实话,PG的Double Buffering也不见得就比别的方法强多少吧
- 问答
- 2026-01-19 14:35:48
- 3
说实话,PG的Double Buffering也不见得就比别的方法强多少吧,这个说法其实在不少实际开发的讨论里都能听到,PG指的是PostgreSQL,一个挺有名的开源数据库,Double Buffering,就是数据在内存里存了两份,一份是数据库自己管理的内存池(shared buffers),另一份是操作系统管理的文件系统缓存,本意是好的,想让数据访问更快,但有时候反而成了累赘,让人觉得它并不比那些只用一层缓存的方法高明。
先从原理上唠唠,PostgreSQL的设计比较传统,它觉得自己管理内存更靠谱,所以搞了个shared buffers,当需要读数据的时候,它先把数据从硬盘读到自己的这个buffer里,但操作系统也有个习惯,它会把最近访问过的文件内容也缓存在内存里,这就是文件系统缓存,结果呢?一份数据,很可能既在shared buffers里躺着一份,又在操作系统的缓存里存着一份,这就造成了内存的浪费,尤其是在内存本来就不太富裕的机器上,这种双重缓存等于占用了两份地方,能用来干别的活的内存就少了,相比之下,像MySQL的InnoDB存储引擎,它就更倾向于利用操作系统的缓存,自己尽量减少重复缓存,看起来就更“经济实惠”一些。
再说说性能,理想情况下,如果shared buffers配置得非常大,能把整个数据库都装进去,那可能感觉不到什么问题,因为大部分数据读取都在自己的缓存里完成了,不怎么需要去碰操作系统的缓存,但现实是,很多数据库都比内存大得多,根本不可能全装进shared buffers,这时候,Double Buffering的毛病就显出来了,当需要读取一个不在shared buffers里的数据时,系统得先检查自己的缓存,发现没有,然后向操作系统发起读取请求,操作系统呢,可能会发现这个数据其实就在自己的文件缓存里,于是直接从那里把数据拷贝到shared buffers,你看,绕了这一圈,数据明明已经在内存里了,却因为分属两个“地盘”,还得进行一次内存之间的拷贝,这白白消耗了CPU资源,如果只有一层缓存,比如直接使用文件系统缓存,这次拷贝就省掉了,效率反而更高,在一些高并发的OLTP场景下,这种额外的开销积累起来,对性能的影响是不能忽视的。
还有配置和维护的麻烦事,用PostgreSQL,数据库管理员得操心shared buffers应该设多大,设小了,缓存命中率低,性能不好;设大了,就像前面说的,不仅可能浪费内存,还可能引发操作系统本身因为内存紧张而进行频繁的交换(swapping),导致系统整体卡顿,这个平衡点并不好找,需要根据具体的工作负载反复调整,而像一些设计上更依赖操作系统缓存的数据库,管理员可能就少操这份心,把内存管理的重任更多地交给成熟的操作系统内核去处理,反而更省事,这种额外的管理成本,也算是Double Buffering带来的一个隐性弱点。
PG的这种设计也有它的历史原因和考量,比如为了确保数据的一致性和可靠性,它需要对自己的缓存有绝对的控制权,但在今天看来,随着操作系统内存管理越来越高效,这种“双保险”的必要性确实受到了一些质疑,很多新的数据库系统都在探索更简洁的缓存架构。
回过头来看,“PG的Double Buffering也不见得就比别的方法强多少”这个说法,是有一定道理的,它并不是一个放之四海而皆优的方案,在内存资源紧张、或者工作负载特定的情况下,它的缺点可能会比优点更突出,选择哪种数据库,不能光看名气,还得结合实际的应用场景和资源状况来判断,PG的这个设计特点,算是一个需要权衡的因素吧。

本文由称怜于2026-01-19发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/83719.html
