PgBouncer
pgbouncer是一个轻量的连接池,可以很好的管理Halo数据库的连接(对客户端连接进行限制,预防过多恶意连接;pgbouncer的每个连接仅消耗2KB的内存资源)。换句话说,它非常高效,它可以以很小的开销容纳数千个连接。
pgbouncer位于数据库和客户端之间。它将保持到数据库的连接是打开的,并确保所需的fork()调用的数量显著减少。
优点:
1)内存消耗低(默认为2k/连接),因为Bouncer不需要每次都接受完整的数据包
2)可以把不同的数据库连接到一个机器上,而对客户端保持透明
3)支持在线的重新配置而无须重启
4)支持在线重启/升级,而不用删除客户端连接
5)pgbouncer 可以限制每一对用户+数据库到Halo Cluster的总连接数
三种连接池模型
1.session
会话级连接,在它的连接生命周期内,连接池分配给它一个数据库连接。客户端断开时,数据库连接会放回连接池中。这是默认的连接模式。
2.transaction
事务级别连接,当客户端的每个事务结束时,数据库连接就会重新释放回连接池中,再次执行一个事务时,需要再从连接池中获取一个连接。
3.statement
每执行完一个SQL时,连接就会重新释放回连接池中,再次执行一个SQL 时,需要再次从连接池中获得连接。这种模式意味着在客户端强制autocomit模式
Pgbouncer 操作
参数:-d :后台运行-R :重启进程-v :详细信息启动pgbouncer:/opt/pgbouncer/bin/pgbouncer -d /etc/pgbouncer/pgbouncer.ini -v重启pgbouncer:/opt/pgbouncer/bin/pgbouncer -R -d /etc/pgbouncer/pgbouncer.ini目前pgbouncer还没有自主停止的脚本或者命令,只能通过kill命令来停止。cat /var/run/pgbouncer/pgbouncer.pid | xargs kill -9

登录 pgbouncer
pgbouncer对外提供了一个虚拟数据库pgbouncer,之所以成为虚拟数据库,是因为它可以提供像普通数据库那样的数据库操作界面,但是这个数据库却并不是真实存在的。而是pgbouncer虚拟出来的一个命令行界面。
[halo@hora ~]$ psql -p 6432 -d pgbouncer -U dbadmin -h 192.168.192.191用户 dbadmin 的口令:psql (14.11 (240421), 服务器 1.22.1/bouncer)输入 "help" 来获取帮助信息.pgbouncer=# show clients;pgbouncer=# show servers;

如果修改了一些配置参数,可以不用重启pgbouncer而是reload使其生效
pgbouncer=# reload;RELOAD注意:只有在配置了参数 admin_users 或者 stats_users才会连接到控制台
ZQPool
ZQPool是使用Go语言编写和发布的数据库连接池软件,主要解决现有生态中流行的一些连接池软件的一些缺点,满足专业客户对连接池软件高性能、高可用的要求。
主要功能:
1)高性能连接池,大幅减少数据库连接数,提高数据库性能。
2)数据库容灾高可用,在出现故障时,恢复时间短,恢复流程简单不易出错,应用侧无感知。
3)支持读写分离,将部分查询负载均衡的发送到多个备库进行查询,充分利用机器资源,分担主库在高峰期的压力。
pgbouncer处理SQL的转发只能用到CPU的一个核,对于高并发的情况下,超过单核的性能时,就立即会出现瓶颈。而ZQPool是使用golang的协程技术,可以利用了多核的性能。
ZQPool 操作
--启动zqpoolsystemctl start zqpool--查看状态systemctl status zqpool

-- 查看一个连接池的后端数据库列表curl -X POST -d "pool_name=kuafu.sundb&mgr_token=csutoken" http://127.0.0.1:9380/api/v1/pool_list_be_db

此处我们配置了集群的VIP所以只显示了一台

-- 为一个连接池增加一个后端数据库curl -X POST \-d "pool_name=kuafu.sundb&db_portal=10.197.166.6:5436" \-H "Content-Type: application/x-www-form-urlencoded" \http://127.0.0.1:9380/api/v1/pool_add_be_db-- 移除指定连接池一个后端数据库curl -X POST -d "pool_name=kuafu.sundb&db_portal=10.197.166.6:5436" http://127.0.0.1:9380/api/v1/pool_remove_be_db注意事项:目前ZQPool只支持md5,还不支持SCRAM-SHA-256的密码验证方式,所以当后端的数据库的验证方式SCRAM-SHA-256或其他加密方式时会报错。
连接池对比

通过连接池减少连接开销
创建连接并不是免费的,它需要消耗资源,在Halo数据库中,我们必须fork整个进程来创建连接。如果连接存在很长时间,这没有问题。但是,为一个非常短的查询fork一个进程可能代价很高。这些成本常常被开发人员和dba所低估。
注意:本次测试环境的Pgbouncer和Zqpool都部署在10.16.6.234这台机器,压测连接池会把请求转发到10.16.6.241,10.16.6.241是压测的数据库集群的VIP。
为了最大化效果,使用了最基本的脚本运行一个测试:
[halo@halo234 ~]$ cat /tmp/sample.sqlSELECT 1;
第一次测试:使用pgbnech压力测试给定 SQL 脚本
[halo@halo234 ~]$ pgbench -c 500 -T 30 -j 2 -f /tmp/sample.sql -U dbadmin -h 10.16.6.241 halo0root
从上面的结果我们可以看到,长连接测试的tps为58523。
第二次测试我们为每个事务将打开一个新的连接(-C),用短连接的方式再次进行相同的测试:
[halo@halo234 ~]$ pgbench -c 500 -T 30 -j 2 -f /tmp/sample.sql -U dbadmin -h 10.16.6.241 -C halo0root
对比第一次测试,我们将速度降低到每秒682个事务,性能下降了大约98.83%。长连接执行"SELECT 1 "比短连接fork()进程后执行"SELECT 1 "的开销要小得多。因此,池化非常有意义,因为它允许我们资源复用。
第三次测试我们在第二次测试的基础上使用pgbouncer和zqpool连接池对Halo数据库进行压测:
Pgbouncer:[halo@halo234 ~]$ pgbench -c 500 -T 30 -j 2 -f /tmp/sample.sql -U dbadmin -p 6432 -h 10.16.6.234 -C halo0root

Zqpool:[halo@halo234 ~]$ pgbench -c 500 -T 30 -j 2 -f /tmp/sample.sql -p 5436 -U kuafu -h 10.16.6.234 -C sundb
通过pgbouncer连接池进行压测得到的tps为4636,对比第二次测试性能提升了大约579.77%。
通过zqpool连接池进行压测得到的tps为4222,对比第二次测试性能提升了大约519.06%。
综上可以得出,在高并发短连接的场景下,连接池可以重用已经建立的数据库连接,避免了频繁地创建和销毁连接的开销,直接从连接池中获取一个连接可以显著减少连接建立的时间,显著提高数据库的性能。同时它还可以对连接数限制防止应用程序过度消耗数据库资源,从而保护数据库服务器的稳定性。
本期分享至此,如您对halo数据感兴趣,请留言关注。




