导言:曾经听说过一句话,用 PostgreSQL 而不用连接池,绝对是坑爹的做法…… 哪怕是像 pgbouncer 这样的“轻量级”连接池,有和没有的区别都不是一般的大。
虽然这句话说得比较绝对,但从某种角度上来讲,这句话是有一定道理的。
PG 是多进程结构,每新增一个会话就会新增一个进程,相对而言对数据库的开销就会比较巨大。
因为在正常业务会话中,有不少session 都有长时间的 idle的状态,而这个状态导致,此时如果需要连接,就需要建立新的进程,来访问数据库,那么连接数就上来了. 而使用pgbouncer的主要原因
PGBrouncer能够缓存和PostgreSQL的连接,当有连接请求进来的时候,直接分配pgbouncer与postgresql之间的空闲连接去执行,而不需要PostgreSQL fork出新进程来建立连接,以节省创建新进程,创建连接的资源消耗。
关键的是pgbouncer是使用libevent进行socket通信,通信效率高。每个连接仅消耗2kB内存。相对pg自身动辄 4MB 的work_mem算是很轻量级了。
如果要用大白话来说,没有使用pgbouncer的连接方式是私家车,如果车子太多,则路就塞满了,而使用了pgbouncer 的方式则类似公交车或小巴, 有人上车有人下车,座位是固定的,所以公交车如果本身有30个座位,但实际上在整个的路途中可不是仅仅支持30个人,至于支持了多少人,那就看连接到数据库的事务执行的快慢,是否能对一个连接进行复用, 这就有点CPU 的分时使用的概念.
pgbouncer支持三种连接池模式:
官网地址:PgBouncer - lightweight connection pooler for PostgreSQL
1、下载最新的release版本 ,1.160.0 版本。
2、登录至云服务器中,并上传pgbouncer至云服务器。
# 安装一个pgbench,后续可以用以测试:
# yum install -y
https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
# yum install -y postgresql11-server
# 创建pgbouncer的存放目录
# mkdir /opt/pgbouncer
# 进入上传的pgbouncer目录中,进行解压:
# tar -xf pgbouncer-1.16.0.tar.gz
# cd pgbouncer-1.16.0
#执行编译安装,并且指定安装路径为/opt/pgbouncer:
# ./configure --prefix=/opt/pgbouncer
# make
# make install
# 注意,在执行第一步的时候,会提示各种依赖库没有安装,此时仅仅需要安装提示的依赖库的devel包即可。如:libevent-devel,openssl-devel
# yum install -y libevent-devel openssl-devel
# 最后把整个文件夹权限都交给postgres用户来进行管理
# chown postgres:postgres /opt/pgbouncer -R
3、执行完以上语句之后,即可将pgbouncer 安装完成。此时就需要仅pgbrouncer 的配置了。
4、当然也可以将上面三个文件拷贝到一个目录中去进行管理,方便一些,相关命令介绍如下:
4、pgbouncer.ini文件如何配置,直接看下面的示例即可:
[databases]
db_rw = host=172.27.32.11
port=5432
dbname=test
db_ro = host=172.27.32.12
port=5432
dbname=test
; 这里 最开始的xxx= 可以任意配置,主要是连接表示,易于记住即可。建议根据业务情况来进行配置。
; 注意应用通过此连接串连接到database中后,无法切换database。
; host, port, dbname 必须为数据库的访问连接信息,我这里将云数据库的主实例配置为db_rw,将此主实例的只读实例配置为db_ro,而我使用客户端访问数据库时候,访问db_ro即访问后面的库。
; 此处还可以配置用户名和密码,但是不建议配置在此,因为业务或者数据库有多个用户,如果配置了用户在此处,就只能使用此用户对数据库进行访问了。如果想要设置哪些用户可以访问,可以用userlist文件来进行限制。
[users]
; 示例:user1 = pool_mode=transaction max_user_connections=10
; 此处配置用户级别的连接池模式,如果针对某一用户有特殊配置可以在此配置,如无,可留空。
[pgbouncer]
listen_addr =
172.27.32.17
listen_port =
5432
; 服务监听地址和端口。
logfile = /opt/pgbouncer/pgbouncer.log
pidfile = /opt/pgbouncer/pgbouncer.pid
unix_socket_dir = /var/run/pgbouncer
unix_socket_mode =
0777
unix_socket_group =
auth_type = trust
auth_file = /opt/pgbouncer/share/doc/pgbouncer/userlist.txt
; 此处auth_type 可以配置md5,但是数据库侧的 pg_hba.conf文件也需要配置为md5,且userlist 配置文件就需要存md5 后的密码,不能配置为明文,如果设置为trust,则需要设置为明文。
pool_mode = transaction
; 连接池模式,可配置 session,transaction,sql,建议使用transaction。默认是session。
max_client_conn =
100
;最大连接数配置
default_pool_size =
20
;默认连接池大小
min_pool_size =
0
reserve_pool_size =
5
reserve_pool_timeout =
3
5、配置userlist.txt:
6、配置完成后,即可通过postgres用户启动pgbouncer。
$ 启动命令:/opt/pgbouncer/bin/pgbouncer -d /opt/pgbouncer/share/doc/pgbouncer/pgbouncer.ini
7、完成启动之后,可通过下列命令查看是否启动成功
$ ps -ef |grep pgbouncer
postgres 17171 1 0 16:41 ? 00:00:00 /opt/pgbouncer/bin/pgbouncer -d /opt/pgbouncer/share/doc/pgbouncer/pgbouncer.ini
$ netstat -anlp|grep pgbouncer
tcp 0 0 172.27.32.17:5432 0.0.0.0:* LISTEN 17171/pgbouncer
测试结果,使用pgbouncer 对性能影响极低,并且更充分利用了连接资源,当前测试的数量集并不大,基于当前测试结果来看,相信在大规模并发场景下,亦能减轻数据库不少负担,但稳定性待验证。
通过PostgreSQL原生连接与pgbouncer进行访问压测看一下执行情况,设定连接为100个,分别都压测2分钟,中间间隔一分钟。
查看数据库监控,可以看到使用了pgbouncer的连接数降低了33%,QPS几乎无变化,平均响应时延也没有明显变化。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。