pgbouncer相关概念和使用

pgbouncer相关概念和使用

1.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支持三种连接池模式:

  • session 这里是针对session来说的,当用户主动释放了连接,pgbouncer才会把其与数据库之间管理的连接进行释放复用。这样的设置本身和PG的连接逻辑的意义基本上一致.所以还不如不用,一般不使用这种模式。
  • Transaction 最常用也是最合适的模式,一个连接的通道分时被 事务 所使用, 这样的好处比上面的session模式对比要明显的多,连接的使用率会跟随相关的分配有更高的复用,和性能方面的提高.当事务从客户端发出之后,pgbouncer会在与数据库之间的连接中找到一个连接是idle的去扔进去执行,完成事务之后,连接将重新被pgbouncer 交给给其他新事务去使用。
  • SQL 类似于autocommit,粒度最细,一条SQL执行即释放连接,连接就会被其他会话所占用掉。虽然资源利用最极致,但是不符合一般业务场景。破坏了事务逻辑。

我们在使用pgbouncer的情况下,应该首选的是transaction 而不是session否则基本上大部分环节下(于业务以及相关设计以有关),session并不能帮助你做什么特别大的改变,大部分连接处于等待的状态.

pgbouncer特点:

  a.内存消耗低(默认为2k/连接),因为Bouncer不需要每次都接受完整的数据包
  b.可以把不同的数据库连接到一个机器上,而对客户端保持透明
  c.支持在线的重新配置而无须重启
  d.仅支持V3协议,因此后端版本须>=7.4 (引自 pgsqldb中文站)

pgbouncer部署方式:

  Pgbouncer没有绑定到一台后端服务器。目标数据库可以驻留在不同的主机上
      单应用:单应用场景主要具体为短连接较多的场景,频繁进行数据库的连接操作,但操作时间较短,均为短连接,所以将pgbouncer于应用服务器部署在同一台服务器,减少应用服务器和pgbouncer之间的开销
      多应用:多应用场景,一般指多个应用服务器连接数据库,因此可以选择将pgbouncer与数据库服务部署在同一台服务器上,减少pgbouncer和数据库之间的开销。
      集群:读写分离场景下pgbouncer的配置与前面配置基本一致,主要区别于要针对读和写进行分别部署pgbouncer,因为pgbouncer本身只是数据库连接池,不具备负载均衡,或高可用,IP漂移等特性,需要结合其他成熟产品进行组合使用====多实例场景主要利用linux系统端口重用技术,这个特性依靠Linux内核上的支持(Linux3.6以上版本),并结合pgbouncer自身支持(设置so_reuseport=1)结合起来形成多实例场景下的pgbouncer使用,可以认为是pgbouncer的高可靠或者高可用,在某一个实例进程故障的情况下,其他实例集成仍然可以处理来自外部的数据库连接请求。从操作系统层面来看,属于多进程共享同一个端口

2.pgbouncer安装

2.1 linux安装

   百度了多篇关于pgbouncer安装的帖子,最后觉得,很合适的,可以参考https://blog.csdn.net/weixin_34378922/article/details/85079208?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165992529016781818778735%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165992529016781818778735&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~pc_rank_v38-10-85079208-null-null.142^v39^pc_rank_v38,185^v2^control&utm_term=Pgbouncer&spm=1018.2226.3001.4187

  核心的是pgbouncer.ini配置:

[databases]
kkdb= host=192.168.120.149 port=5432 user=kkuser password=redhat dbname=a //dbname为实际数据库名,kkdb为a在pgbouncer中的名字,所以在pgbouncer链接的数据库kkdb,实际上是连的a。
postgres= host=192.168.120.149 port=5432 user=postgres password=redhat dbname=b
[pgbouncer]
logfile = /var/log/pgbouncer/pgbouncer.log
pidfile = /var/run/pgbouncer/pgbouncer.pid
listen_addr = *   //127.0.0.1表示local访问,*表示可以外部访问
listen_port = 6432
auth_type = md5
auth_file = /etc/pgbouncer/userlist.txt
admin_users = postgres,kkuser
pool_mode = transaction //用trancation才能体现pgbouncer的优势。
server_reset_query = DISCARD ALL
ignore_startup_parameters = extra_float_digits
max_client_conn = 1000
default_pool_size = 200

  启动pgbouncer ,这里必须以postgresql服务器用户启动,例如postgres。这里需要把pgbouncer的安装目录修改权限为postgres账户

  按此配置,启动pgbouncer后,可以psql -h pgbouncer的ip -p 6432 -U postgres pgbouncer登录pgbouncer,可以把pgbouncer看做一个虚拟的数据库,登录用户为admin_users里面的用户,默认postgres用户。

  可以psql -h pgbouncer的ip -p 6432 -U postgres postgres 登录到数据库b

  可以psql -h pgbouncer的ip -p 6432 -U kkuser kkdb 登录到数据库a

2.2 docker安装

  rancher拉取相应镜像,并配置Environment Variables,然后配置好sevices和ingress,就可以通过2.1中的psql访问了。可详细访问https://hub.docker.com/r/bitnami/pgbouncer中关于镜像和Variables介绍。

 

3.pgbouncer命令及配置详解

   看了很多关于pgbouncer命令配置的帖子,觉得讲的比较细的,可参考https://www.bigtspace.com/archives/9903.html

   命令是指登录pgbouncer后可使用的命令,配置是指pgbouncer.ini中各项配置。

4.pgbouncer项目中使用

  springboot中使用,主要是修改url为pgbouncer对应的ip和port,数据库名为pgbouncer.ini中database部分数据库配置最靠前的内容,,,这种url也可以通过数据库链接工具,来通过pgbouncer链接到实际数据库,前提是pgbouncer.ini中的listen_addr = *  ,*表示可以外部访问

spring:
  datasource:
    url: jdbc:postgresql://192.168.120.149(pgbouncer ip):6432(pgbouncer port)/kkdb(pgbouncer.ini中database部分数据库配置最靠前的内容)?prepareThreshold=0
    driverClassName: org.postgresql.Driver
    username: kkuser(pgbouncer中database中数据库对应的用户名)
    password: redhat (pgbouncer中database中数据库对应的密码)

5.pgbouncer效果

 由于云服务器中病毒,暂时不能展示,后期有时间补上。

欢迎批评指正!

posted @ 2022-09-01 11:25  金露雪莲  阅读(1036)  评论(0编辑  收藏  举报