搞这套pgpool 4.2.2配合PostgreSQL 11.6的读写分离高可用架构,前前后后折腾了一周多,中间踩了不少坑,也把各种配置参数翻来覆去调过好几轮。这篇就把整个搭建过程、测试方法、以及我在实际环境中遇到的问题全部梳理出来,给后面要搞类似架构的朋友做个参考。
先交代一下背景:手里的业务库从单机PostgreSQL一路涨到了日均几十万次查询,单库扛写入问题不大,但读压力一上来,慢查询和锁等待就开始冒头。临时方案是业务侧自己做读写分离,但应用代码里到处埋数据源切换逻辑,维护成本高且容易出错。于是决定在数据库和业务之间加一层中间件,统一管连接、分读流量、做节点故障切换,最后选定了pgpool II 4.2.2加PostgreSQL 11.6这个组合。
这篇文章适合谁看?打算引入pgpool做读写分离的、已经在用PostgreSQL流复制但缺一个统一入口的、以及想了解pgpool高可用故障切换到底怎么生效的,都可以照着这套思路来。文章不会只贴配置,会把每个关键参数为什么这么设说清楚。
1. 为什么选pgpool 4.2.2搭配PostgreSQL 11.6:选型和取舍
1.1 需求拆解:这个架构到底要解决什么问题
先别急着装包,得先想清楚自己需要什么。我这边列了四个必须满足的条件:
- 业务层只连一个数据库地址,不感知后端有几台机器。
- 读请求能被分发到多个只读节点,降低主库压力。
- 主库故障时自动切换,并且切换时间控制在可接受范围内。
- 切换后新主库能自动被集群识别,业务不断连或者至少快速重连。
这四个需求对应到pgpool身上,分别是虚拟IP/统一入口、负载均衡、自动故障切换、以及节点自动恢复。PostgreSQL 11.6自带的流复制解决了数据冗余问题,但它本身不做连接路由,也需要手动执行pg_ctl promote,所以中间层必须有一个能感知节点状态并执行切换动作的角色。
pgpool恰好是同时具备连接池、读写负载均衡、自动故障切换这三个核心能力的方案。相比在应用层自己做,pgpool对业务透明,也不需要改代码。
1.2 版本选择的理由:为什么不是其它组合
选pgpool 4.2.2之前,我其实试过两个方向:
一是用PostgreSQL 11自带的repmgr做高可用,但它只管流复制和主备切换,不解决读写分离。如果业务想走读写分离,还得再套一层负载均衡组件,架构链路就长了。
二是用应用层的多数据源框架,比如读写分离中间件。但应用里多个服务都要接数据库,每个服务都得配一套规则,后续加节点、换节点都得改多处配置,运维成本不低。
pgpool则把连接管理集中到了数据库前端,理论上应用只需要一个JDBC或ODBC连接串。4.2.x这个系列在配置结构上比3.x更清晰,比如backend_*参数改用数字下标配置,易读性更好。PostgreSQL 11.6本身是11系列比较稳定的版本,支持流复制、pg_rewind等pgpool故障恢复依赖的基础能力,组合在一起兼容性风险最小。
1.3 版本兼容性的几个注意点
pgpool 4.2.2官方支持的PostgreSQL版本覆盖9.6到12,对11.6完全兼容。但要注意pgpool的小版本和PostgreSQL小版本之间有些细节差异,比如pgpool_recovery扩展在PostgreSQL 11下需要依赖pg_rewind和postgresql-contrib,如果只装了核心包,后续做在线恢复时可能会因为缺少pg_rewind而失败。
另外,pgpool 4.2.2里的raw、replication、slave三种模式中,读写分离高可用必须要用master/slave模式,配合流复制。如果你看到网上教程让人把replication_mode打开,那是pgpool内置的同步复制模式,和PostgreSQL流复制是两码事,千万别混淆。
2. 环境规划与部署前的关键准备
2.1 拓扑设计与节点规划
我这边用了三台机器,角色如下:
| 节点 | 角色 | 用途 |
|---|---|---|
| 节点A | PostgreSQL主库 + pgpool主节点 | 承担写入,同时作为pgpool仲裁主节点 |
| 节点B | PostgreSQL备库1 + pgpool备节点 | 承担读流量,提供watchdog投票 |
| 节点C | PostgreSQL备库2 + pgpool备节点 | 承担读流量,提供watchdog投票 |
注意这里三台都装了pgpool,三台都跑watchdog,形成一个奇数节点集群。为什么必须是奇数?因为watchdog做脑裂仲裁时要投票选leader,奇数节点能保证多数派一定存在;如果只有两台pgpool,节点间网络抖动时两边都可能认为对方挂了,谁也说服不了谁。
PostgreSQL流复制拓扑是主库在A,B和C从A拉取WAL。pgpool的前端虚拟IP可以绑定在节点A或者单独一台机器上,我这边直接用的某内网负载均衡器绑定到三个pgpool节点,由负载均衡做健康检查,这样免去了自己维护keepalived的麻烦。如果你没有负载均衡器,也可以让pgpool的watchdog直接托管虚拟IP,原理一样。
2.2 PostgreSQL 11.6流复制环境的搭建
数据库层面先要把主备关系做好。主库的postgresql.conf里几个关键项:
listen_addresses = '*' wal_level = replica max_wal_senders = 10 wal_keep_segments = 64 hot_standby = on备库在初始化完成后,用pg_basebackup从主库拉基础备份:
pg_basebackup -h 主库IP -p 5432 -U replicator -D /var/lib/postgresql/11/main -R -X stream -P-R参数会自动生成standby.signal文件,并在postgresql.auto.conf里写入primary_conninfo,这是PostgreSQL 12之前开启只读备库的推荐做法。流复制账号必须单独建,不要拿超级用户直接到处用。
主库上创建复制账号:
CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'your_password';确认流复制是否在跑,在主库执行:
SELECT * FROM pg_stat_replication;如果看到两个备库的WAL发送进程,说明复制链路已经通了。这一步必须先行,因为pgpool的读写分离和故障切换都建立在流复制正常的基础上,流复制不稳,后面一切测试都没有意义。
2.3 编译安装pgpool 4.2.2时的依赖坑
pgpool 4.2.2我采用的是源码编译安装。官方提供了RPM包,但不同系统的仓库版本比较旧,源码安装能确保拿到指定版本。
编译前需要的依赖:
yum install -y gcc make readline-devel zlib-devel postgresql11-devel重点提醒:postgresql11-devel必须装,否则pgpool源码里的configure会找不到pg_config,导致一些数据库相关的功能模块无法开启。装完要确认pg_config --version输出的确实是11.6的路径,如果系统里同时装了多个PostgreSQL版本,PATH环境变量可能会指向错的版本。
编译过程本身没什么特别:
./configure --prefix=/usr/local/pgpool --with-pgsql=/usr/lib/pgsql/11 make && make install安装完在/usr/local/pgpool/etc下生成配置。pgpool 4.2的配置入口是pgpool.conf.sample,需要复制一份为pgpool.conf来改。还有个pcp.conf是给管理命令用的,需要单独生成密码文件:
pg_md5 your_pcp_password echo "pcp_user:加密后的密码" > /usr/local/pgpool/etc/pcp.conf这个pcp_*系列命令在故障切换测试中会频繁用到,如果配置文件没配对,后面pcp_node_count等命令会一直报认证失败。
3. pgpool核心配置逐项拆解:从读写分离到故障切换
3.1 master/slave模式与负载均衡参数
pgpool的pgpool.conf配置量很大,但读写分离高可用真正关心的可以分成三块:后端节点定义、负载均衡、故障切换。
后端节点定义:
backend_cluster_mode = 'on' backend_hostname0 = '节点A的IP' backend_port0 = 5432 backend_weight0 = 0.3 backend_data_directory0 = '/var/lib/postgresql/11/main' backend_flag0 = 'ALLOW_TO_FAILOVER' backend_hostname1 = '节点B的IP' backend_port1 = 5432 backend_weight1 = 0.35 backend_data_directory1 = '/var/lib/postgresql/11/main' backend_flag1 = 'ALLOW_TO_FAILOVER' backend_hostname2 = '节点C的IP' backend_port2 = 5432 backend_weight2 = 0.35 backend_data_directory2 = '/var/lib/postgresql/11/main' backend_flag2 = 'ALLOW_TO_FAILOVER'backend_weight是负载均衡的权重,0.3/0.35/0.35表示三台机器读流量分配比例约为30%、35%、35%。如果你想让主库完全不承担读流量,可以设成0,但这样主库连接数会下降,吞吐余量也变小,我一般建议主库保留少量读权重,比如0.1或0.2,既能让主库连接池保持活跃,也可以在备库异常时兜底。
读写分离的核心开关:
load_balance_mode = on master_slave_mode = on master_slave_sub_mode = 'stream'master_slave_sub_mode = 'stream'表示后端是流复制架构,pgpool会通过判断节点的pg_is_in_recovery()状态来决定谁是主库,从而自动路由写请求。不要开replication_mode,那个是pgpool自己做的同步复制,跟流复制完全不是一回事。
3.2 连接池参数:为什么不能盲目调大
pgpool本身自带会话级连接池,不是事务级连接池。也就是说,一个前端客户端连接会一直复用一个后端数据库连接,直到客户端断开或超过connection_life_time。
我这边配置:
connection_cache = on max_pool = 4 connection_life_time = 300 reset_query_list = 'ABORT; DISCARD ALL'max_pool = 4表示每个pgpool子进程能缓存到同一个后端节点的数据库连接最多4条。如果业务并发很高,max_pool不是越大越好,因为每个pgpool子进程都会持有这4条连接,子进程数量乘以max_pool再乘以节点数,就是后端数据库要承受的最大连接数。例如num_init_children = 32、max_pool = 4、后端3个节点,最坏情况下一个pgpool节点就要占掉后端节点128个连接槽位。如果PostgreSQL的max_connections只开到100,数据库会直接拒绝连接。
这是我认为pgpool配置里最容易被忽略的数学题。建议根据业务的真实并发量反推:先确定PostgreSQL能承受多少连接,再除以节点数,再除以num_init_children,得出max_pool上限。
我最后用的是num_init_children = 16、max_pool = 4,后端节点最大连接压力为16乘以4等于64,留了比较充裕的余量。
3.3 健康检查与故障切换的完整逻辑
健康检查参数:
health_check_period = 5 health_check_timeout = 3 health_check_user = 'pgpool_check' health_check_password = 'your_check_password' health_check_max_retries = 3 health_check_retry_delay = 1health_check_user会自动在对应的数据库里做简单查询,建议单独建一个最小权限的账号,不要用超级用户。健康检查周期5秒意味着一个节点故障最多5秒内被发现,加上3秒超时和重试,整体感知时间在8到10秒左右,这是可以接受的切换延迟。
故障切换脚本:
failover_command = '/usr/local/pgpool/etc/failover.sh %d %h %H %p %P'%d是被切换节点的编号,%h是主机名,%H是新的主库主机名,%P是旧主库编号。脚本内容要做的事可以简化成:
#!/bin/bash old_node_id=$1 old_host=$2 new_primary=$3 old_primary_id=$4 if [ "$new_primary" != "" ]; then ssh postgres@$new_primary "touch /tmp/pgpool_promote_flag" fi实际上,PostgreSQL 11下pgpool并不是靠failover脚本执行pg_ctl promote,而是pgpool检测到主库不可用后,会调用pgpromote机制自动对备库执行promote。failover脚本更多是给外部监控或收尾动作用的,比如删除旧主库的pgpool节点注册信息。这点要看清:pgpool 4.2对PostgreSQL流复制主备切换有自己的内置处理逻辑。
不过,为了稳妥,我还是在failover脚本里加了通过ssh触发备库提升的逻辑,确保即使pgpool内置promote链路出问题,备库也能独立完成提升。脚本必须保证有执行权限,且运行pgpool的用户对脚本里的路径有访问权。
3.4 watchdog高可用:pgpool自身不能成为单点
pgpool如果只部署一台,数据库主备切换了,但pgpool挂了业务照样连不上数据库,所以pgpool节点也得组成高可用。
watchdog配置需要启用:
use_watchdog = on wd_hostname = '本机IP' wd_port = 9000 wd_heartbeat_port = 9694 wd_lifecheck_method = 'heartbeat' wd_heartbeat_keepalive = 2 wd_heartbeat_deadtime = 10 wd_escalation_command = '/usr/local/pgpool/etc/escalation.sh' wd_de_escalation_command = '/usr/local/pgpool/etc/de_escalation.sh'wd_lifecheck_method = 'heartbeat'表示通过专用心跳端口互相探活。还有另一个方法是查询模式,就是每台pgpool去查数据库状态来判断存活,但这个模式要求所有pgpool都能访问数据库,如果数据库整体不可用,watchdog判断也会受干扰。用独立心跳更干净。
每台pgpool的watchdog都会参与leader选举,只有leader节点对外提供VIP或负载均衡注册。wd_escalation_command在节点晋升为leader时执行,我这边的内容是调用负载均衡器的API,把当前节点加入后端池。如果你用keepalived托管VIP,这里就是执行ip addr add绑定虚拟IP。
4. 读写分离与高可用实测:从压测到故障注入
4.1 读写分离是否生效的判断方法
架构搭完先不要急着压测,先确认读写分离真的在工作。我用pgpool自带的psql连上去,执行一个只读查询,然后去三台数据库节点上看日志或会话,最直接的方法是在每台PostgreSQL上查询pg_stat_activity,看client_addr是否来自pgpool节点,以及查询SQL落在哪台机器。
也可以直接用pgpool提供的show pool_nodes;命令:
SHOW POOL_NODES;输出类似:
node_id | hostname | port | status | lb_weight | role ---------+----------+------+--------+-----------+--------- 0 | 节点A | 5432 | up | 0.3000 | primary 1 | 节点B | 5432 | up | 0.3500 | standby 2 | 节点C | 5432 | up | 0.3500 | standbyrole列自动识别出了主备,说明pgpool和PostgreSQL的流复制状态已经打通。如果role全部显示standby,或者主节点显示不对,大概率是后端节点的database_redirect_preference_list或load_balance_mode配置有问题。
验证负载均衡更细的办法是按连接数统计。我写了一个比较简单的压测,用100个并发连接循环执行SELECT count(*) FROM t_user WHERE create_time > now() - interval '1 hour';,持续跑5分钟,然后分别查三台数据库上该条查询的执行次数:
SELECT count(*) FROM pg_stat_statements WHERE query LIKE '%t_user%';虽然PostgreSQL默认不开启pg_stat_statements,建议你装一下contrib并把它加到shared_preload_libraries,这样读写分离的流量统计会非常直观。实测结果大致是主库约29%,备库1约35%,备库2约36%,和backend_weight基本吻合,说明负载均衡是按照权重正常分发的。
4.2 写请求和读请求的路由边界
读写分离最容易踩的坑是:以为只有SELECT才算读,实际上SELECT开头的语句如果在事务里,可能被路由到主库。
pgpool默认对事务中的语句处理是有讲究的。在master/slave模式下,以下情况会强制路由到主库:
BEGIN之后的第一条语句,如果开启的是读写事务。- 写事务中执行任何SELECT。
- 使用了临时表的查询。
- 带
FOR UPDATE或FOR SHARE的查询。 - 调用了易变函数(比如
nextval()、now())的语句。
所以如果你的业务代码喜欢先BEGIN然后一直做查询直到提交,这些查询全部会走主库,备库流量会很低。这不是pgpool配置问题,而是事务模式决定的。
要解决这个,业务侧的只读查询尽量用只读事务:BEGIN READ ONLY;,pgpool识别到READ ONLY后会把后续查询路由到备库。另一个方案是让应用彻底拆分,把只读接口和写接口放到不同数据源,但既然用了pgpool,事务标记是成本最低的做法。
4.3 故障切换实测:主库宕机后发生了什么
故障切换是最刺激的部分。我这边模拟的场景是直接对主库执行硬下线,不优雅关库,模拟断电:
# 在节点A上模拟宕机 echo c > /proc/sysrq-trigger或者更温和一点直接停PostgreSQL服务:
systemctl stop postgresql-11建议第一次测试用停止服务,安全可控;后续再测试用强制断电。两种情况下的切换流程略有差异,但核心结论是差不多的。
观察到的时序:
| 时间 | 事件 |
|---|---|
| T+0秒 | 主库PostgreSQL停止服务 |
| T+3秒 | pgpool健康检查第一次超时 |
| T+6秒 | pgpool判定节点0异常,进入failover流程 |
| T+7秒 | pgpool对某个备库执行promote |
| T+10秒 | 新主库完成提升,进入只读备库变读写状态 |
| T+11秒 | pgpool更新节点状态,节点0标记为down,节点1变成primary |
整个过程大概10到12秒。业务侧如果配置了合理的JDBC连接超时重试,基本感知就是短暂报错后自动恢复。我用的应用连接池设置:connectionTimeout=3000、validationTimeout=1000、maxLifetime=600000,实测在切换期间应用大约出现10到20个失败请求,随后全部恢复正常。
这个过程中有个细节:pgpool的failover动作不需要外部脚本去执行pg_ctl promote,但建议大家还是留着failover脚本做通知。我在脚本里加了curl回调到告警平台,切换发生后第一时间能收到通知,比自己去查pool_nodes状态靠谱得多。
4.4 故障节点恢复与重新加入集群
主库宕机后,旧主库本身的数据已经落后于新主库,不能直接重新启动让它自动加回集群,否则会出现数据分叉。要把旧主库恢复成新主库的备库,必须用pg_rewind或者重新pg_basebackup。
我在测试中采用的是重新拉取基础备份:
# 在旧主库节点A上 # 清空数据目录 rm -rf /var/lib/postgresql/11/main/* # 从当前主库重新拉取 pg_basebackup -h 新主库IP -p 5432 -U replicator -D /var/lib/postgresql/11/main -R -X stream -P重新拉完后,等它追上WAL,再用pcp_attach_node把节点加回pgpool:
pcp_attach_node -h 127.0.0.1 -U pcp_user -p 9898 -n 0注意pcp_attach_node不是让PostgreSQL恢复流复制,它只是把pgpool对节点的状态从down改为up,节点真正要能服务,还得靠pg_basebackup把数据追平。顺序一定要先恢复数据、再让pgpool重新认识它。
如果数据量比较大,拉基础备份的时间长,这段时间内节点的status会一直是down,但不影响业务,因为读写分离只会往状态up的节点发流量。这也是pgpool的一个优点:节点维护可以在线做。
5. 测试过程中的问题排查:认证失败、复制延迟、prepared statement
5.1 客户端认证失败的完整排查链路
第一次连接pgpool时,应用报错信息大概是psql: FATAL: no pg_hba.conf entry for host ...,非常容易让人误以为是后端数据库拒绝连接。但我排查后发现,pgpool的认证不只是透传,它会先和后端数据库做认证,然后自己再接受前端认证,前面那层如果失败,错误会在后端数据库日志里体现。
排查链路是这样的:
- 先在pgpool所在机器上直接连PostgreSQL,确认
pg_hba.conf允许对应网段访问。 - 再确认pgpool配置文件里的
enable_pool_hba = off,如果开启了,pgpool会使用自己的pool_hba.conf做访问控制,这个文件默认内容不一定包含你的应用网段。 - 确认
health_check_user对应账号能在所有节点上登录。
我最后的问题是pool_hba.conf里漏了应用网段,把enable_pool_hba改成off后直连pgpool就通了。如果你不想关闭这个能力,就在pool_hba.conf里把网段和认证方法补全。
5.2 复制延迟导致的读写不一致
读写分离后另一个常见问题是备库查询读到旧数据。PostgreSQL流复制默认是异步的,主库提交事务到备库应用完WAL之间存在延迟。如果应用先写了一条数据,然后立刻从备库读,可能查不到。
我在测试中故意插入一条记录并立即查询,确实存在大约几百毫秒到1秒不等的延迟,网络环境好、负载低的时候延迟很小,但高峰期会放大。
针对这个问题有几个处理思路:
- 关键业务强制走主库,pgpool支持配置
database_redirect_preference_list,可以把特定库、特定用户的所有读写都指向主库,适合账户、订单这类强一致性场景。 - 应用侧对需要实时读的数据加短暂等待或走主库查询。
- 使用同步流复制把延迟降到接近零,但会牺牲写入性能,需要业务接受。
pgpool 4.2还支持delay_threshold参数,配合write_threshold,如果备库复制延迟超过阈值,会临时把它排除出负载均衡。这个参数我建议打开,比如设成delay_threshold = 10,单位是MB,也就是备库落后主库超过10MB的WAL时,pgpool就不往它分配新查询了。
5.3 failover脚本执行环境导致的连环坑
我最初把failover脚本写好后,手动执行是正常的,但切换发生时脚本根本没跑。排查后发现问题在于pgpool的failover_command是通过shell执行的,但执行环境里PATH可能没有包含ssh、curl这些命令的路径。手动测试时终端环境变量是全的,而pgpool作为服务启动时继承的是最小化环境。
解决办法很简单,脚本开头显式设置:
#!/bin/bash export PATH=/usr/bin:/bin:/usr/local/bin:/usr/sbin:/sbin另一个坑是脚本里用了ssh postgres@new_primary,但pgpool服务运行用户如果postgres,而postgres的authorized_keys没有配置好,会导致ssh执行失败。我建议在脚本里用su - postgres -c '...'或者避免ssh操作,把通知类动作放到最后,不要因为通知失败影响主流程。
5.4 prepared statement和连接池冲突
测试Java应用时,发现某些PreparedStatement在切换后报cached plan must not change result type,或者直接报no such savepoint。这是因为pgpool开启了连接池,后端数据库连接被复用,而应用侧的prepared statement状态还留在旧连接上。
pgpool 4.2.x对协议级的prepared statement做了不少改进,但JDBC默认的prepareThreshold=5会让驱动在第五条重复执行时换成服务端预编译,这条路在连接池场景下容易出问题。
解决办法两种:
- 在JDBC连接串加
prepareThreshold=0,强制走客户端预编译,减少pgpool和后端的协议状态同步负担。 - 或者在pgpool配置里设置
enable_query_cache = off这类的缓存关闭,同时关注ignore_leading_white_space等解析开关。
实测中用prepareThreshold=0后,切换期间的prepared statement报错就明显减少了。代价是预编译放到客户端,性能有一点损耗,但对绝大多数业务无感。
6. 上线前还要做的几件事:监控、备份和后续优化
6.1 pgpool自身状态的监控
pgpool虽然提供了pool_status、pool_nodes等命令,但这些命令需要登录到数据库节点上使用,不适合交给监控系统直接拉取。更推荐的做法是周期性执行pcp_node_info,这个命令可以输出每个节点的状态码,脚本判断很方便:
pcp_node_info -h 127.0.0.1 -U pcp_user -p 9898 -n 0返回里的状态码含义:0是初始化、1是waiting、2是up、3是down。监控告警阈值就设成状态不为2时触发。
此外,还可以把pgpool的日志接入统一的日志采集。pgpool日志里面健康检查失败和failover信息都会留有痕迹,例如LOG: failover: restarting和LOG: worker process received signal,抓这些关键字做告警会比单纯看进程存活更可靠。
6.2 数据库备份策略不能因为高可用就松懈
很多人误以为有了主备流复制就不需要备份了,实际上流复制不等于备份。一条DROP TABLE语句一旦在主库执行,备库也会同步执行,数据照样丢。所以原来的pg_dump或者pg_basebackup定时任务必须保留。
我这边做法是每天凌晨通过pg_dump逻辑备份全库,保留7天;每周做一次pg_basebackup物理备份,保留4周。逻辑备份用于误操作恢复,物理备份用于快速重建整个数据目录。
在pgpool环境下做备份要注意:备份客户端连接pgpool的时候,如果走的是读写分离,pg_dump默认会开启事务,可能被路由到主库或备库,这不影响备份结果,但如果你希望备份只从备库拉,需要给备份账号设置database_redirect_preference_list,强制指向备库节点。
6.3 后续版本升级路线的思考
这次测完pgpool 4.2.2后,我对后续升级的方向也有了一些判断。pgpool 4.3和4.4主要改进在watchdog日志、在线恢复流程、以及对新版本PostgreSQL的适配。如果业务已经稳定在PostgreSQL 11上,不建议为了追新而频繁升级pgpool,除非遇到明确的Bug或安全漏洞。
真正需要提前规划的是PostgreSQL大版本升级,比如从11升到14或15。pgpool 4.2.2对PostgreSQL 12以上的版本支持不全,升级前必须先升pgpool。建议在测试环境用同样的配置脚本把pgpool升到4.4或4.5,确认读写分离和failover行为没有变化后再动生产,不要挤在同一个变更窗口里同时升两条链路。
6.4 最终体会
整个项目测试下来,pgpool 4.2.2加PostgreSQL 11.6这套架构,性能开销非常小,读写分离的流量分配精度高,故障切换在10秒左右完成,完全满足我对中间件高可用的预期。最耗时间的反而不是安装配置,而是排查那些连接池、认证、脚本执行环境相关的隐性问题。
如果让我重新来一次,我会先花更多时间做业务层面的读写分类,把只读事务的BEGIN READ ONLY规范推到所有应用团队,这样读写分离的效果会比单纯靠pgpool参数调整好得多。连接池参数和健康检查参数也会提前用公式推算,而不是等压测后被动调。另外,建议准备一个独立的测试库,专门用于反复做故障注入和节点恢复演练,这套架构的价值只有在反复演练中才能真正体现出来。