PostgreSQL 为什么接受大量连接到数据库需要连接池

Stella981
• 阅读 1047

PostgreSQL 是非常好的开源的数据库,针对替换ORACLE数据库的重任,基本上大部分中小型企业,能指望的也只有POSTGRESQL ,当然如果你愿意花更多的前,更多的应用程序结构方面的改造,MYSQL 也不是不可以, ORACLE 换成PG 就如同,你从一个中单的一个房间 换到另一个房间, 如果要是ORACLE 到MYSQL ,就如同你从北京,搬到上海. 所以如果不想大动干戈, 并且不想改变现有的整体架构, PG 一定是必然的选择,没有其他.

那在使用PG的时候,可能很快就会体会到PG之美, 与功能强大,这里就不在多说,今天要说的是,POSTGRESQL 在高并发下,超高连接对PG的冲击,以及为什么PG 在高并发连接中,需要使用pgbouncer或pgpool 来.

首先就要祭出原理, 到底连接分配的内存要从哪里来出,大部分人包括我,认为,导致PG 无法接受大量连接的主要原因,其实是内存. 由于大量的连接使用了大量的内存,导致,PG 在接受大量的connections 会导致, OOM, 或者性能低下.

PostgreSQL  为什么接受大量连接到数据库需要连接池

PostgreSQL  为什么接受大量连接到数据库需要连接池

但实际上我们做一个测试,我对一个有用8G 内存的 PG  ,加载3000个并发连接并且查询一个表,同时将 shared_buffers 调整成20MB ,然后我就等待着PG崩溃.

PostgreSQL  为什么接受大量连接到数据库需要连接池

PostgreSQL  为什么接受大量连接到数据库需要连接池

PostgreSQL  为什么接受大量连接到数据库需要连接池

实际上我并没有如愿, PG 还是稳稳的运行, 但系统有一点缓慢,有点卡的感觉

内存方面

PostgreSQL  为什么接受大量连接到数据库需要连接池

也并没有像我与预期的会彻底的用光.

那么问题来了, 到底各种 大小广而告之,中提到的PG 不适宜 多连接的原因在哪里.

那就的从 PG 的源码中的 PGPROC 说了, 

PostgreSQL  为什么接受大量连接到数据库需要连接池

PostgreSQL  为什么接受大量连接到数据库需要连接池

其中上面的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的跟踪

PostgreSQL  为什么接受大量连接到数据库需要连接池

PostgreSQL  为什么接受大量连接到数据库需要连接池

PostgreSQL  为什么接受大量连接到数据库需要连接池

而为了获取这些信息的变化对share_buffer 和 backend  的临时数据进行获取,他会遍历到其他的process 中, 而如果我们建立的backend越多, 也就是连接到PG的连接越多, 就会导致遍历GetSnapshotData 的工作消耗更多的系统资源,例如CPU.

PostgreSQL  为什么接受大量连接到数据库需要连接池

由于查询是最简单的 select 语句,并且应该也应用到了缓存,IO性能基本上处于没有使用的状态

PostgreSQL  为什么接受大量连接到数据库需要连接池

PostgreSQL  为什么接受大量连接到数据库需要连接池

内存的使用也未占满.

多连接并不是通过内存的消耗,将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 人员应该做的。

PostgreSQL  为什么接受大量连接到数据库需要连接池

本文分享自微信公众号 - AustinDatabases(AustinDatabases)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
RAC环境单实例启动数据库收到ORA
     在RAC环境中,如果你在没有启动节点的集群服务的情况下单实例启动数据库,将收到类似如下的报错:\oracle@rhel1u01\$sqlSQL\Plus:Release10.2.0.5.0ProductiononTueApr215:00:272013Copyright(
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这