PostgreSQL 为什么不能并发太高与PG14 如何解决关键问题

2021-09-01 00:00:00 连接 内存 并发 进程 性能



MYSQL 的并发在硬件配置OK的情况下, 4000- 5000 都是可以的, 相对PostgreSQL 一直被吐槽的高并发连接下的性能问题,可能的原因有两点


没有缓冲池造成的频繁的打开和关闭连接,造成的内存频繁的分配,释放回收,以及连接存在期间的 idle 的连接,长时间拥有分配的内存造成的内存损耗和性能损失

源代码中关于GetSnapshotData() 中获取 PGXACT-> xmin 多次获取导致的高并发下 CPU 消耗异常,.导致性能低下.


以下内容为说明和验证


我们以Postgresql 11 为例, 我们打开4个连接, 这样看如果不清晰,我们换一种方式看.但我们再看的时候,记录一下四个连接的PID 


我们可以看到以postgres 1629 为主进程的下面在除了各个POSTGRESQL 功能模块的子进程以外, 我们的访问的连接也是挂在postgres 的主进程下的.

如例: 2969 2971 2844 2851 

通过命令我们可以看到这些进程与1629之间的关系. 


在POSTGRESQL 的设计中, 这些子进程我们叫backend process, 


下面是的源代码是对上面图的一个说明, 每一个backend都有一个 PGPROC的结构在 shared memory中, 这个结构是可以被复用的, 这里包含了一个进程PID 与 数据库连接之间的对应关系. 在POSTGRESQL  中各个backend processes 之间是无法看到相互的内存使用的情况, Postmaster 本身也不能查看backend process 内存.  但各个进程之间要进行互访的情况下, postmaster 就必须要跟踪每个进程的情况.


PGPROC 主要控制等待信息,latch 锁状态同步, 事务ID协调,以及锁等待和处理 pg_stat_activity 视图.




在POSTGRESQL 的守护进程Postmaster 接收到了客户的连接请求,会开始为客户启动一个backend 进程, src/backend/postmaster/postmaster.c

 

压力测试中发现连接在idle的状态下,是hold住内存, POSTGRESQL 本身没有connection pool 每一次打开和关闭连接,都会牵扯内存的分配和释放, 频繁的内存的分配和释放会影响整体系统的性能.  


在POSTGRESQL 14 中提到提升整体高并发时的 POSTGRESQL 的性能

根据官方的邮件显示, Andres Freund  对GetSnapshotData() 中的 PGXACT ->min进行了修改提高了整体的高并发时的系统性能.

https://www.postgresql.org/message-id/20200301083601.ews6hz5dduc3w2se%40alap3.anarazel.de



对两个版本的PG进行相关的测试, 版本为 11  ,  14 beta3 ,机器的配置同为 2CORE  4G 内存 share buffer  2G  ,  work_mem 40MB , 其他配置均不变压入通过pgbench 压入1000万数据.通过 500 并发来对两个版本的POSTGRESQL 进行压测.


经过下面的测试, PG14beta3 在修改了问题代码后, 整体比PG11.7 性能提高了 50%  TPS 从797 提高到  1489






那么就期待 POSTGRESQL 在高并发场景下的好性能吧 !



相关文章