PgBouncer使用最佳实践
PgBouncer介绍
PgBouncer是为PostgreSQL提供的轻量级连接池工具,作用如下:
- 能够缓存和PostgreSQL的连接,当有连接请求进来的时候,直接分配空闲进程,而不需要PostgreSQL fork出新进程来建立连接,以节省创建新进程,创建连接的资源消耗。
- 能够有效提高连接的利用率,避免过多的无效连接,导致数据库消耗资源过大,CPU占用过高。
- 对客户端连接进行限制,预防过多或恶意的连接请求。
轻量级体现在:
- 使用libevent进行socket通信,通信效率高。
- C语言编写,效率高,每个连接仅消耗2KB内存。
PgBouncer目前支持三种连接池模型:
- session会话级连接。只有与当客户端的会话结束时,PgBouncer才会收回已分配的连接。
- transaction事务级连接。当事务完成后,PgBouncer会回收已分配的连接。也就是说客户端只是在事务中才能独占此连接,非事务请求没有独享的连接。
- statement语句级连接。任何数据库请求完成后,PgBouncer都会回收连接。此种模式下,客户端不能使用事务,否则会造成数据的不一致。
PgBouncer默认选项是session,建议修改为transaction。
安装配置
在云上部署PgBouncer连接池,需要先购买弹性云服务器。建议选择与后端RDS实例相同VPC、相同子网创建,降低网络通信时延。购买成功后登录ECS进行环境搭建。
- 由于PgBouncer是基于libevent开发,需要安装libevent-devel openssl-devel两个依赖包。命令如下:
yum install -y libevent-devel yum install -y openssl-devel
- 依赖包安装后,在PgBouncer官网下载源码,以普通用户身份进行编译、安装。
su - pgbouncer tar -zxvf pgbouncer-1.19.0.tar.gz cd pgbouncer-1.19.0 ./configure --prefix=/usr/local make make install
- 创建如下目录,用于保存PgBouncer的生成文件(日志、进程标识等)。
mkdir -p /etc/pgbouncer/ mkdir -p /var/log/pgbouncer/ mkdir -p /var/run/pgbouncer/
- 启动PgBouncer前,需要构建配置文件“pgbouncer.ini”。
[databases] * = host=127.0.0.1 port=5432 [pgbouncer] logfile = /var/log/pgbouncer/pgbouncer.log pidfile = /var/run/pgbouncer/pgbouncer.pid listen_addr = * listen_port = 6432 auth_type = md5 auth_file = /etc/pgbouncer/userlist.txt admin_users = postgres stats_users = stats, postgres pool_mode = transaction server_reset_query = DISCARD ALL max_client_conn = 100 default_pool_size = 20 ;; resolve: unsupported startup parameter: extra_float_digits ;;ignore_startup_parameters = extra_float_digits
配置文件中各参数含义可参考PgBouncer官方文档。
启动pgbouncer
PgBouncer不能以root身份启动,需要基于普通用户身份进行启动。
pgbouncer -d /etc/pgbouncer/pgbouncer.ini
启动后,可通过netstat -tunlp | grep pgbouncer查看连接池的监听端口,而后进行连接:
psql -U root -d postgres -h 127.0.0.1 -p 6432 Password for user root: psql (12.13) Type "help" for help. postgres=> \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+-----------+----------+-------------+-------------+------------------------- postgres | pgbouncer | UTF8 | en_US.UTF-8 | en_US.UTF-8 | template0 | pgbouncer | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/pgbouncer | | | | | pgbouncer=CTc/pgbouncer template1 | pgbouncer | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/pgbouncer
停止PgBouncer
可以直接通过Kill命令停止。
kill `cat /var/run/pgbouncer/pgbouncer.pid`
cat /var/run/pgbouncer/pgbouncer.pid | xargs kill -9
PgBouncer管理
PgBouncer对外提供了一个虚拟数据库pgbouncer,之所以称为虚拟数据库,是因为它可以提供像PostgreSQL那样的数据库操作界面,但是这个数据库却并不是真实存在的,而是PgBouncer虚拟出来的一个命令行界面。登录虚拟数据库:
psql -p 6432 -d pgbouncer
如果修改了一些配置参数,可以不用重启PgBouncer而是reload使其生效。
pgbouncer=# reload; RELOAD
登录后可以通过show help查看命令帮助,通过show clients查看客户端连接信息,通过show pools查看连接池信息。
实现读写分离示例
PgBouncer并不支持自动解析读写请求,并进行读写分离路由,需要业务侧对读写操作进行区分。
- 首先,修改配置文件“pgbouncer.ini”配置的数据库信息,添加主库、只读库连接配置。本例中参数设置如下:
[databases] ;; * = host=127.0.0.1 port=5432 #配置只读库的连接信息 mydb_read:host=10.7.131.69 port=5432 dbname=postgres user=root password=*** # 配置主库的连接信息 mydb_write: host=10.8.115.171 port=5432 dbname=postgres user=root password=*** [pgbouncer] logfile = /var/log/pgbouncer/pgbouncer.log pidfile = /var/run/pgbouncer/pgbouncer.pid listen_addr = * listen_port = 6432 auth_type = md5 auth_file = /etc/pgbouncer/userlist.txt admin_users = postgres stats_users = stats, postgres pool_mode = transaction server_reset_query = DISCARD ALL max_client_conn = 100 default_pool_size = 20 ;; resolve: unsupported startup parameter: extra_float_digits ;;ignore_startup_parameters = extra_float_digits
- 分别连接主库、只读数据库进行验证。通过psql成功连接只读、主库,可支持业务读写分离。
psql -U root -d mydb_write -h 127.0.0.1 -p 6432 Password for user root: psql (14.6) mydb_write=> SELECT pg_is_in_recovery(); pg_is_in_recovery ---------------------- f (1 row) psql -U root -d mydb_read -h 127.0.0.1 -p 6432 Password for user root: psql (14.6) mydb_read=> SELECT pg_is_in_recovery(); pg_is_in_recovery ---------------------- t (1 row)