PostgreSQL 是很是好的开源的数据库,针对替换ORACLE数据库的重任,基本上大部分中小型企业,能期望的也只有POSTGRESQL ,固然若是你愿意花更多的前,更多的应用程序结构方面的改造,MYSQL 也不是不能够, ORACLE 换成PG 就如同,你从一个中单的一个房间 换到另外一个房间, 若是要是ORACLE 到MYSQL ,就如同你从北京,搬到上海. 因此若是不想大动干戈, 而且不想改变现有的总体架构, PG 必定是必然的选择,没有其余.
数据库
那在使用PG的时候,可能很快就会体会到PG之美, 与功能强大,这里就不在多说,今天要说的是,POSTGRESQL 在高并发下,超高链接对PG的冲击,以及为何PG 在高并发链接中,须要使用pgbouncer或pgpool 来.
缓存
首先就要祭出原理, 到底链接分配的内存要从哪里来出,大部分人包括我,认为,致使PG 没法接受大量链接的主要缘由,实际上是内存. 因为大量的链接使用了大量的内存,致使,PG 在接受大量的connections 会致使, OOM, 或者性能低下.微信
但实际上咱们作一个测试,我对一个有用8G 内存的 PG ,加载3000个并发链接而且查询一个表,同时将 shared_buffers 调整成20MB ,而后我就等待着PG崩溃.架构
实际上我并无如愿, PG 仍是稳稳的运行, 但系统有一点缓慢,有点卡的感受
并发
内存方面数据库设计
也并无像我与预期的会完全的用光.
高并发
那么问题来了, 到底各类 大小广而告之,中提到的PG 不适宜 多链接的缘由在哪里.
post
那就的从 PG 的源码中的 PGPROC 说了,
性能
其中上面的each backend has a PGPROC struct in shared memory , + 后面的那句, 应该代表 backend 和 shared memory 之间 存在一个pgproc的结构, 这个结构的主要做用就是 复用.
测试
后面的NOTE 的twophase.c 证实了PGPROC 结构的复用,由于当前的transaction 在队列中 有两个状态, 真正运行和准备运行.
这个PGPROC 会在 PROC_HDR中被调用, allProcs 是一个指针,也就是全部的PGPROC 都会在这里面.PGPROC 主要的做用是要在事务处理期间处理相关例如等待和处理等工做之间的切换,PROC 主要的做用进程间协同和通信以及postmaster的跟踪
而为了获取这些信息的变化对share_buffer 和 backend 的临时数据进行获取,他会遍历到其余的process 中, 而若是咱们创建的backend越多, 也就是链接到PG的链接越多, 就会致使遍历GetSnapshotData 的工做消耗更多的系统资源,例如CPU.
因为查询是最简单的 select 语句,而且应该也应用到了缓存,IO性能基本上处于没有使用的状态
内存的使用也未占满.
多链接并非经过内存的消耗,将PG 带入到OOM 和系统无响应的状况中, 而是随着backend变多后,内部沟通的成本过高,致使性能上的问题,因此PG的在多链接中,是须要使用PGPOOL 或者 pgbouncer 之类的缓冲池来保证系统的性能,另外还有一个问题就是为何要有这么多的链接, 这就是一个问题.
那既然知道了PG在处理超多的链接上会有性能的问题,那如何解决这个问题对大多数使用的人就有相关的意义,能够带着这个问题来问几个问题
内存的使用也未占满.
多链接并非经过内存的消耗,将PG 带入到OOM 和系统无响应的状况中, 而是随着backend变多后,内部沟通的成本过高,致使性能上的问题,因此PG的在多链接中,是须要使用PGPOOL 或者 pgbouncer 之类的缓冲池来保证系统的性能,另外还有一个问题就是为何要有这么多的链接, 这就是一个问题.
那既然知道了PG在处理超多的链接上会有性能的问题,那如何解决这个问题对大多数使用的人就有相关的意义,能够带着这个问题来问几个问题。
1 为何要有并发有那么多的链接, 例如一个数据库要承受3000+以上的链接数,即便是互联网属性,总体的架构设计是什么,若是并发的链接不少的状况下,数据库自己可能已经分库分表,或者已经经过业务继续细分,将访问分散了。因此过多的同一时间的访问,这自己就是一个问题
2 对于数据库的访问,即便不使用PGbouncer 或者pgpool 程序自己也有链接池,对于链接的设计,在总体的程序设计之初就应该有考虑,而不是最后让数据库承接这一切
3 对于任何的数据库链接,都不是百分之百在同一时刻达到最大的处理数,及时是MYSQL 3000 MAX CONNECTIONS链接,在很细分的时间刻度上,同时访问数据库的基本也就是几十个。PG 的链接状态分为
1 active
2 idle
3 idle in transacton
4 aborted
这里PGbouncer 和PGPOOL 到底在帮助PG connections 作了什么
1 和 3,4 不是咱们要关心的,而是idle 这个状态,这也是大部分浪费链接数的关键位置,由于程序的链接池要维护一个链接数据库的状态,这也就致使有些时刻PG 大部分的链接的状态在idle,因此要更高的利用 链接,让数据库使用有限的链接,接入更多的要工做的链接就是解决,少链接和应用要多链接的矛盾,所谓的链接复用。。
2 另外若是你常常发现你的链接状态在 idle in transaction 这也就说明常常有大事务长时间在等待什么,这也是解决问题的一个点,为何一个事务要长时间霸占链接,并等待
另外还有一些链接,只链接不清理不关闭,多是程序设计有失误,这样的状况咱们能够设置对某个数据库的链接的 statement_timeout ,在多长时间不工做咱们就关掉这个链接。(设置60秒)
alter database 数据库名 set statement_timeout = 60000;
这里最后总结一下
1 每一个数据库有本身的特性,这和数据库设计的之初,架构思路有关
2 数据库的特性不是很好修改的,例如到目前MYSQL 也仍是比较适合作OLTP,也没有人让他去作OLAP的操做同样, 过分将一个数据库神话,样样都行这不现实。
3 掌握某个数据库的特色,并展开,让自己的缺点弱化,这才是一个 DB 人员应该作的。
本文分享自微信公众号 - AustinDatabases(AustinDatabases)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。